简介
Optional是一个容器对象,它可能包含某个值,也可能不包含,它的设计目的是为了解决空指针异常问题。
使用Optional可以避免在代码中显式地检查null值。
不过这个类有好有坏,适当使用即可,其缺点就是造成代码过于冗长,最主要是引入额外的对象开销。
常见的Optional用法
现有一个实体类UserVo
,该类有两个属性username
、password
,下述示例以该实体类测试。
创建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()
按需选择即可。