1 Optional要点
Optional 是Java8提供的为了解决null安全问题的一个API;
Optional使用要点:
1)使用 Optional 时尽量不直接调用 Optional.get() 方法;
2)Optional.isPresent() 更应该被视为一个私有方法;
3)应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法;
//Optional 中我们真正可依赖的应该是除了 isPresent() 和 get() 的其他方法
public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
public T orElse(T other)
public T orElseGet(Supplier<? extends T> other)
public void ifPresent(Consumer<? super T> consumer)
public Optional<T> filter(Predicate<? super T> predicate)
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
2 Optional方法介绍
2.1 三种构造方式
# 1 Optional.of(obj)
明确将要传入obj 参数不可能为 null 时使用;
# 2 Optional.ofNullable(obj)
智能、宽容的方式来构造一个 Optional 实例, 传 null 进到就得到 Optional.empty(),非 null 就调用 Optional.of(obj);
# 3 Optional.empty()
new 一个Optional返回;
2.2 主要方法
除了上边的三个的:
1)isPresent():判断是否存在;
2)ifPresent(Consumer consumer):存在才对它做点什么;
3)get():获取Optional实例的value;
4)filter(Predicate predicate):存在则以断言型lambda表达式进行过滤;
5)map(Function mapper) :存在则以函数型lambda表达式进行转换;
6)flatMap(Function mapper):判断是否为空;
7)orElse(T other):存在即返回, 无则提供默认值;
8)orElseGet(Supplier other):存在则执行供给型lambda表达式并返回, 无则由函数来产生空Optional对象;
方法使用案例:
public static void main(String[] args) {
//构造两个Student实例 一个为null 一个非null
Student weision = new Student("Weision", 10, 99);
Student noName = null;
//orElse1 存在即返回, 无则提供默认值
Student student = getStudentOrElse(noName);
System.out.println("getStudentOrElse-->她的名字是getStudent: " + student.getName());
//orElse2 存在即返回, 无则提供默认值
String name = getNameorElse(noName);
System.out.println("getNameorElse-->她的名字是getName: " + name);
//orElse3 存在即返回, 无则提供默认值
String name1 = getNameorElse(weision);
System.out.println("getNameorElse-->我的名字是: " + name1);
//orElseGet1 存在即返回, 无则由函数来产生
Student student1 = getStudentOrElseGet(noName);
System.out.println("getStudentOrElseGet-->我的名字是: " + student1.getName());
//orElseGet2 存在即返回, 无则由函数来产生
Student student2 = getStudentOrElseGet(weision);
System.out.println("getStudentOrElseGet-->我的名字是: " + student2.getName());
//isPresent1 存在才对它做点什么
StudentisPresent(weision);
//isPresent2 存在才对它做点什么
//StudentisPresent(noName);
//map1 存在就对它做点加工
String name2 = StudentMap(noName);
System.out.println("StudentMap-->我的名字是: " + name2);
//map2 存在就对它做点加工
String name3 = StudentMap(weision);
System.out.println("StudentMap-->我的名字是: " + name3);
//flatMap1 存在就对它做点加工
String name4 = StudentflatMap(noName);
System.out.println("StudentflatMap-->我的名字是: " + name4);
//flatMap2 存在就对它做点加工
String name5 = StudentflatMap(weision);
System.out.println("StudentflatMap-->我的名字是: " + name5);
//filter1 存在才对它进行过滤
String name6 = StudentFilter(noName);
System.out.println("StudentFilter-->大于9岁的人是: " + name6);
//filter2 存在才对它进行过滤
String name7 = StudentFilter(weision);
System.out.println("StudentFilter-->大于9岁的人是: " + name7);
}
//存在即返回, 无则提供默认值
public static Student getStudentOrElse(Student student) {
return Optional.ofNullable(student).orElse(new Student("无名氏", 10, 60));
}
//存在即返回, 无则提供默认值
public static String getNameorElse(Student student) {
return Optional.ofNullable(student).map(stu -> stu.getName()).orElse("无名氏");
}
//存在即返回, 无则提供默认值
public static Student getStudentOrElseGet(Student student) {
return Optional.ofNullable(student).orElseGet(() ->
new Student("无名氏", 10, 60)
);
}
//存在才对它做点什么
//Optional.of(T) 适合明确T非空时使用
public static void StudentisPresent(Student student) {
Optional.of(student.getName()).ifPresent(System.out::println);
}
//存在才对它做点什么
public static String StudentMap(Student student) {
return Optional.ofNullable(student).map(s -> s.getName()).orElse(null);
}
//存在才对它做点什么 flatMap与map方法 入参不一样 其他没区别
public static String StudentflatMap(Student student) {
return Optional.ofNullable(student).flatMap(a -> Optional.of(a.getName())).orElse("没名字");
}
//存在才对它进行过滤
public static String StudentFilter(Student student) {
return Optional.ofNullable(student).filter(stu -> stu.getAge() > 9)
.map(s -> s.getName()).orElse("没有人大于9岁");
}
执行结果:
getStudentOrElse-->她的名字是getStudent: 无名氏
getNameorElse-->她的名字是getName: 无名氏
getNameorElse-->我的名字是: Weision
getStudentOrElseGet-->我的名字是: 无名氏
getStudentOrElseGet-->我的名字是: Weision
Weision
StudentMap-->我的名字是: null
StudentMap-->我的名字是: Weision
StudentflatMap-->我的名字是: 没名字
StudentflatMap-->我的名字是: Weision
StudentFilter-->大于9岁的人是: 没有人大于9岁
StudentFilter-->大于9岁的人是: Weision
3 总结
Optional<String> stringOptional = Optional.ofNullable("123");
Optional<String> nullStringOptional = Optional.ofNullable(null);
boolean present = stringOptional.isPresent(); //true
boolean present1 = nullStringOptional.isPresent();//false
stringOptional.ifPresent(str -> System.out.println(str));//print
nullStringOptional.ifPresent(str -> System.out.println(str));// don't print
//orElse和orElseGet 只是入参数不同 意思是一样的
String str = stringOptional.orElse("456");//123
String str2 = nullStringOptional.orElse("789");//789
String str3 = stringOptional.orElseGet(() -> "345"); //123
String str4 = nullStringOptional.orElseGet(() -> "789"); //789
//value为null时 map不会执行
String str5 = stringOptional.map(s -> s + "000").orElse("444");//123000
String str6 = nullStringOptional.map(s -> s + "000").orElse("444");//444
//value为null时 filter不会执行
String str7 = stringOptional.filter(s -> str.length() > 2).orElse("555");//123
String str8 = stringOptional.filter(s -> str.length() > 3).orElse("555");//555
String str9 = nullStringOptional.filter(s -> str.length() > 1).orElse("555");//555
//value为null时 flatMap不会执行 flatMap 与 map的区别是 出参
String str10 = stringOptional.flatMap(s -> Optional.ofNullable(s + "111")).orElse("666");//123111
String str11 = nullStringOptional.flatMap(s -> Optional.ofNullable(s + "111")).orElse("666");//666
orElse()需要一个值,orElseGet()需要一个lambda表达式
private List<Student> getStudentList(List<Student> studentList) {
return Optional.ofNullable(studentList)
.map(students -> students.stream()
.filter(student -> student.getAge() > 10)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
}
private List<Student> getStudents(List<Student> studentList) {
return Optional.ofNullable(studentList)
.map(students ->
students.stream()
.filter(student -> student.getAge() > 10)
.collect(Collectors.toList()))
.orElse(new ArrayList<>());
}
POJO中使用Optional避免外层get某属性时频繁得判断非空
public class PrimarySchoolClass {
private String className;
private Teacher headmaster;
private List<Teacher> teachers;
private List<Student> students;
public Teacher getHeadmaster() {
return Optional
.ofNullable(headmaster)
.orElseGet(Teacher::new);
}
public void setHeadmaster(Teacher headmaster) {
this.headmaster = headmaster;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Teacher> getTeachers() {
return Optional
.ofNullable(teachers)
.orElseGet(ArrayList::new);
}
public void setTeachers(List<Teacher> teachers) {
this.teachers = teachers;
}
public List<Student> getStudents() {
return Optional
.ofNullable(students)
.orElseGet(ArrayList::new);
}
public void setStudents(List<Student> students) {
this.students = students;
}
}