JAVA8新特性之Optional类

7/21/2022 JAVA8

# 前述

  • 变量存在时,Optional 类只是对类简单封装。变量不存在时,缺失的值会被建模成一个“空”的Optional对象,由方法Optional.empty()返回。

  • Optional.empty()方法是一个静态工厂方法,它返回Optional类的特定单一实例。

  • Optional,本质上是一个容器对象,拥有一个非空值或空值,需要我们将对象实例传入该容器中。如果值存在,Optional.isPresent()方法返回true,并通过Optional.get()方法获取值。

  • Optional的构造方法为private,无法直接使用new来创建Optional对象,只能使用Optional提供的静态方法创建

# 创建方法

Optional.of(obj):如果对象为 null,将会抛出NullPointerException。

● Optional.ofNullable(obj):如果对象为 null,将会创建不包含值的 EMPTY Optional对象实例(new Optional<>())。

● Optional.empty() :等同于 Optional.ofNullable(null)
1
2
3
4
5

# Optional的使用

# get

获取Optional中的值,这个值也就是我们的值,Optional相当于就是一个外壳。

 public class OptionalTest {
     public static void main(String[] args) {
         User user = null;
         Optional<User> optional = Optional.ofNullable(user);
         User user1 = optional.get();
     }
 }
1
2
3
4
5
6
7

# isPresent()

判断Optional对象中是否有值,如果有值,返回 true ,没值返回 false

 public class OptionalTest {
     public static void main(String[] args) {
         User user = new User();
         Optional<User> optional = Optional.ofNullable(user);
         System.out.println(optional.isPresent());
     }
 }

 public class OptionalTest {
     public static void main(String[] args) {
         User user = null;
         Optional<User> optional = Optional.ofNullable(user);
         System.out.println(optional.isPresent());
     }
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# ifPresent(Consumer<? super T> consumer)

ifPresent参数是一个函数式接口,无返回值,会将Optional中的值作为参数传递到ifPresent()

 public class OptionalTest {
     public static void main(String[] args) {
         User user = new User();
         Optional<User> optional = Optional.ofNullable(user);
         optional.ifPresent(s -> System.out.println(s));
     }
 }
1
2
3
4
5
6
7

# filter(Predicate<? super T> predicate)

是一个Predicate函数接口,会将Optional中的值作为参数传入,如果符合规则,那么返回一个Optional对象,否则返回一个空的Optional 对象 (Optional.empty)

public class OptionalTest {
     public static void main(String[] args) {
         User user = new User();
         user.setUsername("xxx");
         Optional<User> optional = Optional.ofNullable(user);
         Optional<User> optional1 = optional.filter(v -> v.getUsername().equals("xxx"));
         System.out.println(optional1);
     }
 }
1
2
3
4
5
6
7
8
9

# map(Function<? super T, ? extends U> mapper)

  • 参数是一个Function函数式接口,会将Optional中的值作为参数传递到map

  • 如果传入的值为空,则返回一空的Optional对象,相当于Optional.empty()

  • 如果不为空,我们可以返回一个可以描述结果的返回值(Optional中的值,这个值可以重新赋值)

 public class OptionalTest {
     public static void main(String[] args) {
         User user = null;
         Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
         System.out.println(optional); //Optional.empty
     }
 
     public static String getMap(User user){
         return user.getUsername();
     }
 }

 public class OptionalTest {
     public static void main(String[] args) {
         User user = new User();
         user.setUsername("xxx");
         user.setAge(20);
         Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
         System.out.println(optional); 
     }
     public static String getMap(User user){
         return user.getUsername();
     }
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# flatMap(Function<? super T, Optional> mapper)

  • 如果Optional中值存在,那么返回一个基于Optional的值(如Optional)

  • 如果Optional中的值不存在,则返回一空的Optional对象,相当于Optional.empty()

  • map不同之处在于:map返回的是一个值,而flatMap返回一个基于Optional的值

 public class OptionalTest {
     public static void main(String[] args) {
         User user = new User();
         user.setUsername("xxx");
         user.setAge(20);
         Optional<String> optional = Optional.ofNullable(user).flatMap(OptionalTest::getFlatMap);
         System.out.println(optional); 
     }

     public static Optional<String> getFlatMap(User user){
         return Optional.ofNullable(user).map(User::getUsername);
     }
 }
1
2
3
4
5
6
7
8
9
10
11
12
13

# orElse(T other)

如果Optional中的值不为空,则返回Optional中的值,如果为空,则返回other值

 String value = "2";
 String orElse = Optional.ofNullable(value).orElse("1");  
 System.out.println(orElse);  //2  
         
 String value = null;
 String orElse = Optional.ofNullable(value).orElse("1"); 
 System.out.println(orElse);  //1
1
2
3
4
5
6
7

# orElseGet(Supplier<? extends T> other)

如果Optional中存在值,则返回值,否则返回other调用的结果

 public class OptionalTest {
     public static void main(String[] args) {
         String value = null;
         String orElse = Optional.ofNullable(value).orElseGet(OptionalTest::get);
         System.out.println(orElse);  // 123
     }
     public static String get(){
         return "123";
     }
 }
1
2
3
4
5
6
7
8
9
10

# orElseThrow(Supplier<? extends X> exceptionSupplier)

如果Optional中的值存在,则返回值,值不存在,则抛出异常函数Supplier中的异常

 public class OptionalTest {
     public static void main(String[] args) {
         String value = null;
         String orElse = Optional.ofNullable(value).orElseThrow(() -> new RuntimeException("不存在值"));
         System.out.println(orElse);
     }
 }
1
2
3
4
5
6
7

# 几种If场景优化

# 1、Optional.orElse

String name = null != people ? people.getName() : "Unknown";

if (null != people.getName()) {
    throw new RuntimeException();
}


// Optional 类提供两个方法 orElse 与 orElseThrow ,可以方便完成上面转化。

// 设置默认值
String name = optional.orElse(new People("Unknown")).getName();
// 抛出异常
String name = optional.orElseThrow(RuntimeException::new).getName();
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2、Optional.filter

if (null != people && "xxxx".equals(people.getName())) {
	System.out.println("ok");
}

// 使用Optional类提供的方法filter,可以很好的重构:
optional.filter(people1 -> "xxxx".equals(people.getName()))
		.ifPresent(x -> System.out.print("ok"));
1
2
3
4
5
6
7

# 3、对象属性判断


String name = "Unknown";
if (null != people) {
	if (null != people.getName()) {
    	name = people.getName();
    }
}
return name;

// 使用 Optional 重构

Optional<People> optional = Optional.ofNullable(people);
return optional.map(People::getName).orElse("Unknown");
1
2
3
4
5
6
7
8
9
10
11
12
13

# 4、其他示例

常规代码

 if (null != userInfo){
     user.setUsername(userInfo.getName()).setUserAge(userInfo.getAge());
     if (null != userInfo.getEducation()){
         user.setEdu(userInfo.getEducation().getEducation())
                 .setSchool(userInfo.getEducation().getSchoolName())
                 .setAdmissionDate(userInfo.getEducation().getAdmissionTime())
                 .setGraduationDate(userInfo.getEducation().getGraduationTime());
     }
     if (null != userInfo.getFamily()){
         user.setFather(userInfo.getFamily().getFatherName())
                 .setMother(userInfo.getFamily().getMotherName());
     }
 }
1
2
3
4
5
6
7
8
9
10
11
12
13

Optional接口进行改造

Optional.ofNullable(userInfo).ifPresent(userInfoI -> {
    user.setUsername(userInfoI.getName()).setUserAge(userInfoI.getAge());
    Optional.ofNullable(userInfoI.getFamily()).ifPresent(family -> {
        user.setFather(family.getFatherName()).setMother(family.getMotherName());
    });
    Optional.ofNullable(userInfoI.getEducation()).ifPresent(education -> {
        user.setEdu(education.getEducation())
                .setSchool(education.getSchoolName())
                .setAdmissionDate(education.getAdmissionTime())
                .setGraduationDate(education.getGraduationTime());
    });
});
1
2
3
4
5
6
7
8
9
10
11
12