Optional

简介

Optional是一个容器对象,它可能包含某个值,也可能不包含,它的设计目的是为了解决空指针异常问题。
使用Optional可以避免在代码中显式地检查null值。
不过这个类有好有坏,适当使用即可,其缺点就是造成代码过于冗长,最主要是引入额外的对象开销。

常见的Optional用法

现有一个实体类UserVo,该类有两个属性usernamepassword,下述示例以该实体类测试。

创建Optional对象

of()方法

创建一个包含指定非null值的Optional对象

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.of(userVo.getUsername());
        if (usernameOptional.isPresent()) {
            System.err.println("获取的信息为 " + usernameOptional.get());
        } else {
            System.err.println("usernameOptional为空");
        }
    }
}

// 执行结果
获取的信息为 张三

使用of()方法创建了一个包含非null值的Optional对象。然后我们通过调用isPresent()方法检查Optional是否包含值。如果Optional包含值,则调用get()方法获取该值并打印输出;否则打印输出Optional为空。

使用of()方法时,如果传入的值为null,会立即抛出NullPointerException异常。因此,在使用of()方法创建Optional对象时,需要确保传入的值不为空。如果值可能为空,可以使用ofNullable()方法创建Optional对象,该方法可以接受null值。

ofNullable()方法

创建一个包含指定值的Optional对象,如果值为null,则创建一个空的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        // userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        if (usernameOptional.isPresent()) {
            System.err.println("获取的信息为 " + usernameOptional.get());
        } else {
            System.err.println("usernameOptional为空");
        }
    }
}

// 执行结果
usernameOptional为空

使用ofNullable()方法创建了一个包含指定值的Optional对象。如果值为null,则创建一个空的Optional对象。然后我们通过调用isPresent()方法检查Optional是否包含值。如果Optional包含值,则调用get()方法获取该值并打印输出;否则打印输出Optional为空。

使用ofNullable()方法创建的Optional对象可以接受null值,不会立即抛出NullPointerException异常。这样可以更灵活地处理可能为空的值。

empty()方法

创建一个空的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        Optional<String> usernameOptional = Optional.empty();
        if (usernameOptional.isPresent()) {
            System.err.println("获取的信息为 " + usernameOptional.get());
        } else {
            System.err.println("usernameOptional 为空");
        }
    }
}

// 执行结果
usernameOptional为空

使用empty()方法创建了一个空的Optional对象。然后我们通过调用isPresent()方法检查Optional是否包含值。由于我们使用empty()方法创建的Optional对象是空的,所以isPresent()返回值为false,程序会打印输出Optional为空,使用empty()方法创建的Optional对象始终是空的,不包含任何值,这在某些情况下可以用于表示缺失值。

判断Optional是否包含值

isPresent()方法

如果Optional对象包含值,则返回true,否则返回false,上述示例判断部分已经用到

ifPresent()方法

如果Optional对象不为空则执行ifPresent()中的处理逻辑,否则不予执行。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        usernameOptional.ifPresent(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.err.println("业务逻辑处理");
            }
        });
    }
}

userVo正常给userName赋值时

输出结果:业务逻辑处理

没有赋值时,不输出任何结果

获取Optional中的值

get()方法

如果Optional对象包含值,则返回该值,否则抛出NoSuchElementException异常,上述示例判断部分已经用到

注意,使用get()方法时,一定要先使用isPresent()方法来检查Optional对象是否包含值,以避免抛出异常

filter()方法

用于过滤 Optional 对象中的值,只有当值满足特定条件时才保留

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        Optional<String> optional = usernameOptional.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 2;
            }
        });
        System.err.println(optional.get());
    }
}

上述过滤条件为字符串的长度是否为2,是的话取出值

输出结果:张三

但当长度判断不是等于2时,过滤后没有符合条件的数据,会抛出NoSuchElementException异常。

orElse()方法

如果Optional对象包含值,则返回该值,否则返回指定的默认值。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.of(userVo.getUsername());
        // Optional<String> usernameOptional = Optional.empty();
        String string = usernameOptional.orElse("李四");
        System.err.println(string);
    }
}

使用of()方法创建一个非空的Optional对象,并将赋值后的userName作为值传递给它。然后,我们使用orElse()方法获取Optional对象的值,如果Optional对象为空,则返回指定的默认值"李四"。

当示例中调用的是of()方法时

输出结果:张三

当示例中调用的是empty()方法时

输出结果:李四

orElseGet()方法

如果Optional对象包含值,则返回该值,否则通过调用Supplier接口提供的方法来生成一个默认值。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) {
        UserVo userVo = new UserVo();
        // userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        String string = usernameOptional.orElseGet(new Supplier<String>() {
            @Override
            public String get() {
                return "李四";
            }
        });
        System.out.println(string);
    }
}

使用ofNullable()方法创建了一个包含指定值的Optional对象。如果值为null,则创建一个空的Optional对象。然后调用了orElseGet()方法。

运行测试,当userVo正常给userName赋值时

输出结果:张三

没有赋值时

输出结果:李四

orElseThrow()方法

如果Optional对象包含值,则返回该值,否则通过调用Supplier接口提供的方法来抛出指定的异常。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        // userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        String string = usernameOptional.orElseThrow(new Supplier<Throwable>() {
            @Override
            public Throwable get() {
                throw new RuntimeException("抛出指定异常");
            }
        });
        System.err.println(string);
    }
}

userVo正常给userName赋值时

输出结果:张三

没有赋值时

java 复制代码
Exception in thread "main" java.lang.RuntimeException: 抛出指定异常
	at com.sun.test.OptionalTest$1.get(OptionalTest.java:16)
	at com.sun.test.OptionalTest$1.get(OptionalTest.java:13)
	at java.util.Optional.orElseThrow(Optional.java:290)
	at com.sun.test.OptionalTest.main(OptionalTest.java:13)

转换Optional中的值

map()方法

对Optional中的值进行转换,并返回一个新的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        Optional<String> optional = usernameOptional.map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s + " -- 值转换";
            }
        });
        System.err.println(optional.get());
    }
}

创建一个包含指定值的Optional对象,如果值为null,则创建一个空的Optional对象,userVo.getUsername()不为空,走后续逻辑,调用map()方法,生成新的Optional对象,最后用get()方法获取Optional中的值。

输出结果:张三 -- 值转换

flatMap()方法

Optional中的值进行转换,并返回一个新的Optional对象。

java 复制代码
public class OptionalTest {
    public static void main(String[] args) throws Throwable {
        UserVo userVo = new UserVo();
        userVo.setUsername("张三");
        Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
        Optional<String> optional = usernameOptional.flatMap(new Function<String, Optional<String>>() {
            @Override
            public Optional<String> apply(String s) {
                return Optional.ofNullable(s + " -- 值转换");
            }
        });
        System.err.println(optional.get());
    }
}
输出结果:张三 -- 值转换

输出结果与调用map()一样,且该方法处理逻辑稍复杂一些,map()flatMap()按需选择即可。

相关推荐
晨曦_子画1 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
假装我不帅22 分钟前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc
南宫生24 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
神仙别闹24 分钟前
基于ASP.NET+SQL Server实现简单小说网站(包括PC版本和移动版本)
后端·asp.net
Heavydrink37 分钟前
HTTP动词与状态码
java
ktkiko1140 分钟前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
神里大人1 小时前
idea、pycharm等软件的文件名红色怎么变绿色
java·pycharm·intellij-idea
货拉拉技术1 小时前
货拉拉-实时对账系统(算盘平台)
后端
小冉在学习1 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论