Technology Sharing

Learn about Optional in Java in one article

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Introduction to Optional

Optional is a new class introduced in Java 8. Its main problem is NullPointerException.
Original translation (Baidu translation, my English is weak): A container object that may or may not contain a non-null value. If a value is present, isPresent() will return true. If there is no value, the object is considered empty and isPresent() returns false.
Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if a value is not present) and ifPresent() (perform an action when a value is present).
This is a value-based class; programmers should treat equal instances as interchangeable and should not use instances for synchronization, or unpredictable behavior may occur. For example, synchronization may fail in a future release.

The core function I understand here is that isPresent() Method to assist in judging the object as empty, and then passmap(), orElse()ifPresent() The combined use of methods such as , can greatly reduce the lengthy if judgment in the code.

2. Commonly used interfaces

先介绍一下常用所有的接口;
注意:
	1. 此列表是列出了本人觉得有意义的接口不是全部。
	2. 当前jdk版本为17,其他版本可能会没有一些方法,例如:`or()` 方法在jdk1.9中增加的
  • 1
  • 2
  • 3
  • 4
Interface NameBrief description of the function
Optional<T> empty()Construct an emptyOptional Object
Optional<T> of(T value)Construct a non-emptyOptional Object, if为空则报错
Optional<T> ofNullable(T value)Build aOptional Object, empty allowed!
T get()Get a generic object value. If the value为空,则报错
boolean isPresent()If not,null Thentrue
boolean isEmpty()If it is empty,null Thentrue
ifPresent(Consumer)Pass an interface function pair, when the data不为空This function is executed when
ifPresentOrElse(Consumer, Runnable)Two parameters, the first one is executed when it is not empty, the second one is executed when it is empty. Both are interface functions.
Optional<T> filterA filter on the object
Optional<U> map(Function)Conversion Method
Optional<U> flatMap(Function)Conversion method, commonly used to convert multiple layers into one layer
Optional<T> or(Supplier)When you get the object为空When creating a new one based on the interface functionOptionalObject
T orElse(T)When you get the object为空Get a specified generic object when
T orElseThrow()不为空 Returns the object,为空 butNoSuchElementException
T orElseThrow(Supplier)不为空 Returns the object,为空 but指定异常

2.1 Simple use of common interfaces

下面是常用接口的一些简单的演示
  • 1

2.1.1 Common methods of creation

// 1. 构建一个空的 Optional 对象没有任何问题
Optional<Object> empty = Optional.empty();

 // 2. 构建一个非空的 Optional 对象没有任何问题
 Optional<Object> aa = Optional.of("123");
 // 3. 构建一个空的 Optional 对象直接报错  ================ 会报错 of不允许为空
 Optional<Object> bb = Optional.of(null);

 // 4. 构建一个空的 Optional 对象没有任何问题
 Optional<Object> cc = Optional.ofNullable(null);

 // 5. 构建一个非空的 Optional 对象没有任何问题
 Optional<Object> dd = Optional.ofNullable("123");

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.1.2 Common methods for obtaining values


Optional<Object> cc = Optional.ofNullable(null);
// 1. 如果为空的时候获取值就会直接报错
Object o = cc.get();
// 2. 如果对象为空,则获取 or 中的 get 方法的值,否则则获取cc的 get 方法中的值
Object o1 = cc.or(() -> Optional.ofNullable("123")).get();
// 3. 如果对象为空,则直接获取的是 123, orElse()中的参数是非空的。 如果对象不为空则直接获取到对象的值
Object o2 = cc.orElse("123");
// 4. 如果对象为空,则获取 or 中的 get 方法的值,否则则获取cc的 get 方法中的值
Object o3 = cc.orElseGet(() -> Optional.ofNullable("123"));

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.1.3 Common methods of determination

Optional<Object> cc = Optional.ofNullable(null);
// 1. 存在则返回true
boolean present = cc.isPresent();
// 2. 为null返回true
boolean empty = cc.isEmpty();
  • 1
  • 2
  • 3
  • 4
  • 5

2.1.4 Operation method after determination


Optional<Object> cc = Optional.ofNullable(null);
// 1. 如果对象不为空,则执行方法体的内容,否则没有任何操作
cc.ifPresent(item->{
    System.out.println("不为空则执行我"+item);
});

// 2. 如果对象不为空,则执行方法体的内容,否则没有任何操作
cc.ifPresentOrElse(item->{
    System.out.println("不为空则执行我"+item);
},()->{
    System.out.println("为空则执行我");
});

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.2 Introduction to the map method

map 方法的使用跟 Stream 中的map方法一样,我的理解这里面的所有的接口方法与 Stream 中重名的用法都是一样的
  • 1

@Data
public static class User{
    private String name;
    private Integer age;
}
@Test
void getMapTest(){

    User user = new User();
    user.setName("123");
    Optional<User> optionalUser = Optional.of(user);
    // 1. 直接获取 user 对象的 name 的值,这里 map 是当用户不为空的时候执行的
    Optional<String> name = optionalUser.map(User::getName);
    System.out.println(name.isEmpty()); // 输出 false

    Optional<User> optionalUser2 = Optional.ofNullable(null);
    // 2. 直接获取 user 对象的 name 的值,这里 map 是当用户不为空的时候执行的
    Optional<String> name2 = optionalUser2.map(User::getName);
    System.out.println(name2.isEmpty()); // 输出 true
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2.2 Other methods

Other methods:

2.2.1 Filter Method

filter :This method is for filtering,Optional<Path> p = uris. stream().filter(uri -> !isProcessedYet(uri)).findFirst() .map(Paths::get); I have basically never used it here, and I feel there is no usage scenario.

2.2.2 FlatMap Method

flatMap: I understand this method as unboxing conversion: For example, Stream<Optional<T>> Convert toOptional<T>

Stream<Optional<T>> os = ....
Stream<T> s = os.flatMap(Optional::stream)
  • 1
  • 2

3. Common Examples

TODO 这里后面再不吧,暂时也没有太合适的例子
  • 1

4. Conclusion

Optional Introduced in Java 8, it provides a more elegant and safe way to handle potentially null values.or ,orElse , ifPresent Functional methods such as these are used to elegantly determine whether something is empty, and to perform operations after it is not empty. This can reduce multiple layers ofif Judgement makes the code elegant, but the disadvantage is use函数式 method will reduce the readability of the code. And it also requiresLambda You need to have a certain understanding.