Java8新特性学习(二)- Optional类
发布时间:2019-02-20 22:03,
浏览次数:419
, 标签:
Java
Optional
<>背景
Optional是一个容器,用来管理一个对象。主要是用来解决null和NullPointerException问题。
<>Java7 -> Java8 Optional是如何简化你的代码
假设有一个Student类
@Data public 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() { Optional emptyOptional =
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:false nullStudentOptional:null
studentOptional:Student(name=a, age=1)
of()函数传入的Object不能为空,否则会直接抛出空指针异常
ofNullable()函数传入的Object可为空
empty()函数会创建一个空的Optional对象,其value为null
isPresent()
@Test public void testOptionalIsPresent() { Optional
nullStudentOptional= 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():false studentOptional.isPresent():true
isPresent()函数会判断当前Optional容器保存的对象是否不为空,true表示不为空,false表示为空
IfPresent()
@Test public void testOptionalIfPresent() { Optional studentOptional1
= 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() { Optional studentOptional
= Optional.ofNullable(null); Student student = studentOptional.orElseThrow(() ->
new NullPointerException("studentOptional is null")); System.out.println(
"student : " + student); } @Test public void testOptionalOrElseGet() { Optional<
Student> 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 super T, ? extends U> mapper) { Objects.
requireNonNull(mapper); if (!isPresent()) return empty(); else { return Optional
.ofNullable(mapper.apply(value)); } } public Optional flatMap(Function
super T, Optional> 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() { Optional
studentOptional= 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:aa flatMap:aa map:null flatMap:null java.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.