一句话
Optional类是为了很好的解决NPE,看如下的源码的前3行代码,我们就知道Optional是如何防范NPE的:(Optional 是个容器:它可以保存类型T的值,无论该值是否为null。至于是什么设计模式,就不说了)
* @param <T> the type of value
* @since 1.8
*/
public final class Optional<T> {
/**
* Common instance for {@code empty()}.
*/
private static final Optional<?> EMPTY = new Optional<>();
/**
* If non-null, the value; if null, indicates no value is present
*/
private final T value;
...
}
一堆接口
一段代码
class Student {
private Long id;
private String name;
private Double grade;
public Student(Long id, String name, Double grade) {
this.id = id;
this.name = name;
this.grade = grade;
}
// getter & setter
}
public class OptionalLearn {
public void test() {
Student student = new Student(1001L, "test", 99.9D);
Optional<Student> optional = Optional.of(student);
//确定待传入对象不为空,使用of()方法
optional.ifPresent(System.out::println);
//ifPresent 如果存在则执行传入consumer进行消费
Optional<Student> optional1 = Optional.empty();
//构建一个空对象
System.out.println("not null: " + getObject(optional));
System.out.println("null: " + getObject(optional1));
List<Student> students = Lists.newArrayList();
Student student1 = new Student(102L, "java", 93D);
Student student2 = new Student(103L, "python", 98.5);
students.add(student1);
students.add(student2);
Optional<List<Student>> list = Optional.of(students);
String s = list
.map(x -> x.get(0)) //取出第一个元素
.map(x -> x.getName()) //取出第一个元素的name属性
.map(x -> x.toUpperCase()) //将属性的值转换成大写
.map(x -> x += "-->optional!!") //再拼接一个字符串
.orElse(null); //
System.out.println("s:" + s);
}
public Student getObject(Optional<Student> optional) {
return optional.orElseGet(this::generator);
//orElseGet 如果存在该值,则返回该值,否则触发传入的参数,调用该方法
}
public Student generator() {
return new Student();
}
public static void main(String[] args) {
OptionalLearn optionalLearn = new OptionalLearn();
optionalLearn.test();
}
总结
1.Optional.of()、Optional.empty()、Optional.ofNullable()区别:
Optional.of()用于确定传入的对象不为null,比如new 出来的
Optional.empty()用于创建一个空对象
Optional.ofNullable() 用于当你不确定要传入对象是不是为null的情况,看Optional.ofNullable()得源码即可知道,其实最后调用的还是以上两种方法
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
那就有人要问了,为什么不只留一个Optional.ofNullable()就行了,留那么多干嘛?
个人理解:便于做NPE防范,因为用of表示你确定你要传入的玩意儿就不是null,如果你传入一个null,IDEA的语法检查就会告诉你,这里不允许传null,发现问题与编译之前!同理,用empty表示明确知道你要一个null
2.orElseGet 与 orElse 方法的区别在于,orElseGet 方法传入的参数为一个 Supplier 接口的实现 —— 当 Optional 中有值的时候,返回值;当 Optional 中没有值的时候,返回从该 Supplier 获得的值。
3.map()很常用!很常用!!很常用!!!