Overview of the practice of using Java Optional

Question: Don’t give up until the last moment. Regardless of whether the ending is successful or not, as long as you work hard and try your best, you will have a clear conscience.


Java 8 is the most important version of Java since Java 5 (released in 2004). This version contains more than ten new features in language, compiler, library, tools and JVM.
Insert picture description here

The Optional class is an Optional class of the same name introduced by Java 8 in order to solve the problem of null value judgment, borrowing from the Optional class of the google guava class library. This article will describe the use of the Optional class and an overview of common methods.

** You may need
CSDN NetEase Cloud Classroom Tutorial
Nuggets EDU Academy Tutorial
Know almost Flutter series articles

1 Why design Optional?

In Java development, if-else logic judgment is usually used to solve the NullPointerException problem. When there are too many object models nested, too many if-else judgments will form code cumbersome.

Using the Optional class can avoid explicit null value judgment (defensive null check) and avoid code cumbersome caused by excessive if-else judgments.

By using Optional, you can reduce the blankness in the code and realize functional programming.

2 Basic use of Optional

A practical application scenario is to obtain the user's area ID information. The traditional method of obtaining is shown in the following code listing 2-1:

//代码清单 2-1 
//获取用户的地区 code 
publish String getUserCountryCode(UserInfor user){
    
    
    String countryCode = "";
    if (user != null) {
    
    
        Address address = user.getAddress();
        if (address != null) {
    
    
            Country country = address.getCountry();
            if (country != null) {
    
    
                String code = country.getCountryCode();
                if (code != null) {
    
    
                    countryCode = code.toUpperCase();
                }
            }
        }
    }
 return countryCode ;
}

Code Listing 2-1 Re-check if-else can avoid the NullPointerException caused by an object being null during the call. The same effect can be achieved through functional programming of the Optional class as shown in Listing 2-2:

  // 代码清单 2-2
  public String getUserCountryCodByOptional(UserInfor user) {
    
    
    return Optional.ofNullable(user)
        .map(c -> c.getAddress())
        .map(r -> r.getCountry())
        .map(u -> u.getCountryCode())
        .orElseThrow(() -> new IllegalArgumentException(" 无法获取到新的值")).toUpperCase();
  }

Tips
Double colon: and arrow function ->, it is a lambda expression of Java8, which is an anonymous function, as shown in the following code listing 2-3.

 // 代码清单 2-3
  public  void test(){
    
    
 
    ///新建集合
    List<String> list = new ArrayList();
    ///模拟数据
    for (int i = 0; i < 10; i++) {
    
    
      list.add("测试数据 "+i);
    }
    

    //第一种 for循环
    for (int i = 0; i < list.size(); i++) {
    
    
      //获取到 list 中对应索引的值
      String s = list.get(i);
    }


    //第二种 增强for
    for (String  s: list) {
    
    
      //s 即为获取到的list中的值
    }

    //第三种 使用lambda表达式以及函数操作符 ->
    list.forEach((s) -> System.out.println(s));

    //第四种 Java8中使用双冒号::操作符完成
    list.forEach(System.out::println);

  }

The effect sought in the code listing 2-2 can also be achieved using double colons, as shown in the following code listing 2-4:

  // 代码清单 2-4
  public String getUserCountryCodByOptional2(UserInfor user) {
    
    
    return Optional.ofNullable(user)
        .map(UserInfor::getAddress)
        .map(Address::getCountry)
        .map(Country::getCountryCode)
        .orElseThrow(() -> new IllegalArgumentException(" 无法获取到新的值")).toUpperCase();
  }

3 Brief description of Optional

Through the use of Optional in the above code listing, it is very elegant to achieve the effect of functional programming. The following conclusions are summarized.

3.1 Optional object creation

When using Optional, you must first create an Optional object. The two construction methods of the Optional class are both private. Therefore, the new Optional() method that cannot be displayed outside the class is used to create the Optional object.

The Optinal object can be created through the three static methods empty(), of(T value), and ofNullable(T value) provided by the Optional class. Examples are as follows

    // 第一种 创建一个包装对象值为空的Optional对象 一般不使用
    Optional<String> optStr = Optional.empty();
    // 第二种 创建包装对象值非空的Optional对象
    Optional<String> optStr1 = Optional.of("optional");
    // 第三种 创建包装对象值允许为空的Optional对象
    Optional<String> optStr2 = Optional.ofNullable(null);

The second way uses the of method to create an Optional for non-null values. The of method creates an Optional class through a factory method. It should be noted that the parameter passed in when creating an object cannot be null. If the incoming parameter is null, a NullPointerException is thrown.

The third method ofNullable creates an Optional for the specified value. If the specified value is null, it returns an empty Optional.

3.2 map 、flatMap 、filter

The map method of Optional is used to get the value in Optional, and Optional also provides get method to get the value.
Optional's map method is called. If Optional has a value, the mapping function will be executed to get the return value. If the return value is not null, create an Optional containing the return value of the mapping as the return value of the map method, otherwise return an empty Optional.

The simple description is to extract and convert values ​​from the Optional object through the map method.

  public void testMap(){
    
    
    // 第二种 创建包装对象值非空的Optional对象
    Optional<String> optStr1 = Optional.of(" 测试 map 方法数据");

    ///获取 optStr1 中的值
    Optional<String> stringOptional = optStr1.map((value) -> value);
    ///optStr1 有值 所以输出的是  optional
    System.out.println(stringOptional.orElse("orElse输出的内容"));
  }

The unit test effect is shown in the figure below. The
Insert picture description here
flatMap method is similar to the map method. The difference lies in the return value of the mapping function. The return value of the mapping function of the map method can be any type T, and the mapping function of the flatMap method must be Optional. At present, the author has not applied it to actual business scenarios.

If there is a value in the filter method and the assertion condition is met, an Optional containing the value is returned, otherwise an empty Optional is returned.

3.3 orElse 、 orElseGet 、 orElseThrow 方法

OrElse method, if the corresponding Optional has a value, return it, otherwise it returns the other specified value.

The orElseGet method is similar to the orElse method. The difference lies in the default value. The orElse method uses the incoming string as the default value. The orElseGet method can accept the implementation of the Supplier interface to generate the default value.

If orElseThrow has a value, return it, otherwise throw an exception created by the supplier interface. In orElseThrow we can pass in a lambda expression or method, and throw an exception if the value does not exist.

  public void testOrElse(){
    
    
    // 第一种 创建一个包装对象值为空的Optional对象
    Optional<String> optStr = Optional.empty();
    //optStr 无值 所以输出的是 orElse中的内容 "测试 orelse  "
    //orElse 方法接收的参数是字符串
    System.out.println("测试1  "+optStr.orElse("测试 orelse  "));

    // orElseGet 方法接收的是一个函数方法
    System.out.println("测试2  "+optStr.orElseGet(()->"测试 orElseGet  "));

    // orElseGet 方法接收的是一个函数方法 返回值是一个 Throwable
    System.out.println("测试3  "+optStr.orElseThrow(()-> new IllegalArgumentException("空值")));

    // 第二种 创建包装对象值非空的Optional对象
    Optional<String> optStr1 = Optional.of("optional");
    ///optStr1 有值 所以输出的是  optional
    System.out.println(optStr1.orElse("orElse输出的内容"));
  }

The unit test effect is shown in the figure below:
Insert picture description here

4 other

Java 9 added three methods to the Optional class: or(), ifPresentOrElse() and stream().

4.1 or method

The or method, if the value exists, returns the value specified by Optional, otherwise it returns a preset value.

4.2 stream method

The function of the stream method is to convert the Optional to a Stream. If the Optional contains a value, then it returns the Stream containing the value, otherwise it returns an empty Stream.

4.3 ifPresentOrElse method

In java8, the ifPresent method is used to replace the traditional if (user != null) judgment, and there is no support for the operation of if (user != null) else {// xxx}, that is, the ifPresent method of the Optional class in Java8 is not correct The operation of else provides support.

The ifPresentOrElse method in java9 is equivalent to the operation of if (user != null) else {// xxx}.

public void test(UserInfor user) {
    
    
     Optional.ofNullable(user).ifPresentOrElse(u -> {
    
    
         //当user 不为 null 时执行这里
         user.getName();
         user.getAge();
     }, () -> {
    
    
        //当user 为null 时执行这里
         System.err.println("user 对象为null");
     });
}

Public account my big front-end career

Guess you like

Origin blog.csdn.net/zl18603543572/article/details/108273798