写在前面
最开始学java的时候,总能听到别人说java8的新特性,比如lambda表达式,stream流等等。但是第一次接触Optional是在公司前辈的代码中看到的。最开始我还以为是公司自己的工具类,也没太注意。后来才知道他也是java8最重要的一个特性。
关于Optional
简单来说Optional就是解决空指针异常(NullPointerException)的一个类。在平时的代码中空指针异常是最令人头疼的一个问题,举个例子:
int x = a.getB().getX();
System.out.println(x);
该代码很有可能出现空指针问题,规范点来写就应该是:
if (a != null) {
B b = a.getB();
if (b != null) {
int x = b.getX();
System.out.println(x);
}
}
如果嵌套少一点其实也还好,但是一旦多起来就会很麻烦,要写好多层判断就会变得难以维护。此时Optional就是一个很好用的工具。
创建Optional对象
Optional.empty()
创建一个Optional.empty对象。
Optional<String> o1 = Optional.empty();
System.out.println(o1);
// 输出结果:Optional.empty
Optional.of(T value)
创建一个非空的对象,如果换入的参数为null也会报错(NullPointerException)
Optional<String> o2 = Optional.of("123456");
System.out.println(o2);
// 输出结果:Optional[123456]
Optional<String> o3 = Optional.of(null);
System.out.println(o3);
// 出现异常:NullPointerException
Optional.ofNullable(T value)
跟of()一样,但是如果参数为null就相当于执行empty()
Optional<String> o4 = Optional.ofNullable("123465");
System.out.println(o4);
// 输出结果:Optional[123465]
Optional<String> o5 = Optional.ofNullable(null);
System.out.println(o5);
// 输出结果:Optional.empty
判断对象是否存在
可以通过方法isPresent()判断一个Optional 对象是否存在,如果存在,该方法返回true,否则返回 alse——取代obj != null的判断。
System.out.println(Optional.ofNullable("zhangsan").isPresent()); // true
System.out.println(Optional.ofNullable(null).isPresent()); // false
isPresent()也是可以接受一个参数的(可以直接使用lambda表达式)。
例如:
Optional.ofNullable("123456").ifPresent(s -> System.out.println(s)); // 输出123456
orElse(T value)
当一个Optional.empty调用ofElse时就会返回value,也就是说我们可以在一个对象为null时使用orElse来给他一个默认值。
System.out.println(Optional.empty().orElse("默认值")); // 默认值
System.out.println(Optional.ofNullable("张三").orElse("默认值")); // 张三
当然orElse的参数需要和前边的能够进行兼容
过滤与转化
这个就很类似于Stream中的过滤(filter)和转化(map):
- filter() 方法的参数类型为 Predicate(Java 8 新增的一个函数式接口),也就是说可以将一个 Lambda 表达式传递给该方法作为条件,如果表达式的结果为 false,则返回一个EMPTY的Optional 对象,否则返回过滤后的 Optional 对象。
System.out.println(Optional.ofNullable("123456").filter(s -> s.length() > 5)); // Optional[123456]
System.out.println(Optional.ofNullable("123456").filter(s -> s.length() > 10)); // Optional.empty
- map()可以安装一定的规则将一个Optional对象转化为另一个Optional对象,例如:
String value = "123456";
Optional<String> o1 = Optional.of(value);
Optional<Integer> o2 = o1.map(s -> Integer.parseInt(s)); // lambda的简化写法:o1.map(Integer::parseInt);
一个filter和map结合起来的例子,不区分大小写检查密码
import java.util.Optional;
public class Main {
public static void main(String[] args) {
String password = "PASSWORD";
Optional<String> opt = Optional.ofNullable(password);
boolean result = opt.map(String::toLowerCase).filter( pwd -> pwd.length() > 6 && pwd.length() < 10 && pwd.equals("password")).isPresent();
System.out.println(result);
}
}