本文共 5725 字,大约阅读时间需要 19 分钟。
Optional是一个容器,用来管理一个对象。主要是用来解决null和NullPointerException问题。
假设有一个Student类
@Datapublic class Student { private String name; private Integer age; public Student() { } public Student(String name, Integer age) { this.name = name; this.age = age; }}
举例一
//java7 private String getJava7UpperCaseStudentName(Student student) { if (student != null) { String name = student.getName(); if (name != null) { return name.toUpperCase(); } } return null; } //java8 private String getJava8UpperCaseStudentName(Student student) { return Optional.ofNullable(student).map(Student::getName).map(String::toUpperCase).orElse(null); }
举例二
@Test public void testOptionalOrElse() { Student origin = null; Student defaultStudent = new Student("default", -1); //java7 Student java7Student = origin != null ? origin : defaultStudent; //java8 Student java8Student = Optional.ofNullable(origin).orElse(defaultStudent); System.out.println("java7Student : " + java7Student); System.out.println("java8Student : " + java8Student); }
可见,使用Optional可以简化代码。
of()、ofNullable()和empty()
@Test public void testEmptyOptional() { OptionalemptyOptional = Optional.empty(); System.out.println("emptyOptional.isPresent:" + emptyOptional.isPresent()); } @Test public void testOptional() { Optional nullStudentOptional = Optional.ofNullable(null); Optional studentOptional = Optional.of(new Student("a", 1)); System.out.println("nullStudentOptional:" + nullStudentOptional.orElse(null)); System.out.println("studentOptional:" + studentOptional.orElse(null)); }
输出结果
emptyOptional.isPresent:falsenullStudentOptional:nullstudentOptional:Student(name=a, age=1)
of()函数传入的Object不能为空,否则会直接抛出空指针异常
ofNullable()函数传入的Object可为空
empty()函数会创建一个空的Optional对象,其value为null
isPresent()
@Test public void testOptionalIsPresent() { OptionalnullStudentOptional = Optional.ofNullable(null); Optional studentOptional = Optional.of(new Student("a", 1)); System.out.println("nullStudentOptional.isPresent():" + nullStudentOptional.isPresent()); System.out.println("studentOptional.isPresent():" + studentOptional.isPresent()); }
输出结果
nullStudentOptional.isPresent():falsestudentOptional.isPresent():true
isPresent()函数会判断当前Optional容器保存的对象是否不为空,true表示不为空,false表示为空
IfPresent()
@Test public void testOptionalIfPresent() { OptionalstudentOptional1 = Optional.of(new Student("a", 1)); studentOptional1.ifPresent(student -> { System.out.println("accept student:" + student); student.setAge(student.getAge() * 2); student.setName(student.getName() + "-accept"); }); System.out.println("after accept student:" + studentOptional1.orElse(null)); }
运行结果
accept student:Student(name=a, age=1)after accept student:Student(name=a-accept, age=2)
orElseThrow()、orElseGet()
@Test public void testOptionalOrElseThrow() { OptionalstudentOptional = Optional.ofNullable(null); Student student = studentOptional.orElseThrow(() -> new NullPointerException("studentOptional is null")); System.out.println("student : " + student); } @Test public void testOptionalOrElseGet() { Optional studentOptional = Optional.ofNullable(null); Student student = studentOptional.orElseGet(() -> new Student("zz", -1)); System.out.println("student : " + student); }
输出结果
结果1:java.lang.NullPointerException: studentOptional is null at com.common.java8.OptionalTest.lambda$testOptionalOrElseThrow$7(OptionalTest.java:56) at java.util.Optional.orElseThrow(Optional.java:290) at com.common.java8.OptionalTest.testOptionalOrElseThrow(OptionalTest.java:56)...结果2:student : Student(name=zz, age=-1)
map()、flatMap()
public Optional map(Function mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Optional.ofNullable(mapper.apply(value)); } } public Optional flatMap(Function > mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); } }
从方法签名上看,两者返回参数相同,入参Function的返回参数不一样,一个是U,一个是Optional< U >, 但是他们都返回Optional< U >
@Test public void testOptionalMapAndFlatMap() { OptionalstudentOptional = Optional.of(new Student("aa", 11)); System.out.println("map:" + studentOptional.map(Student::getName).orElse(null)); System.out.println("flatMap:" + studentOptional.flatMap(s -> Optional.of(s.getName())).orElse(null)); Optional nameNullOptional = Optional.of(new Student(null, 11)); System.out.println("map:" + nameNullOptional.map(Student::getName).orElse(null)); System.out.println("flatMap:" + nameNullOptional.flatMap(s -> Optional.ofNullable(s.getName())).orElse(null)); System.out.println("flatMap:" + nameNullOptional.flatMap(s -> null).orElse(null)); }
输出结果
map:aaflatMap:aamap:nullflatMap:nulljava.lang.NullPointerException at java.util.Objects.requireNonNull(Objects.java:203) at java.util.Optional.flatMap(Optional.java:241) at com.common.java8.OptionalTest.testOptionalMapAndFlatMap(OptionalTest.java:23)
从上面这种用法两者基本相同。但是在Optional类中,两个方法真正的区别是flatMap返回的必须是一个非空Optional值,否则会抛出NullPointException.
转载地址:http://khnqb.baihongyu.com/