Note: not until the last moment, do not give up, whether the outcome is successful or not, as long as you have struggled, tried to, all have a clear conscience


Java 8 is the most important release of Java since Java 5 (released in 2004). This release includes more than a dozen new features in languages, compilers, libraries, tools, and JVMS.

The Optional class is an Optional class introduced by Java8 to solve the problem of null value determination. This article will describe the use of Optional class and common methods overview.

** You might need
CSDN Netease Cloud classroom tutorial
The Denver nuggets EDU College Courses
zhihu Series of articles on Flutter

1 why design Optional?

In Java development, if-else logic judgments are often used to solve nullPointerExceptions. When there is too much nesting of the object model, too many if-else judgments will result in code burdensome.

Using the Optional class avoids explicit NULL values (a defensive check for NULL) and avoids code burdensome from excessive if-else values.

Use Optional to reduce nulls in code and achieve functional programming.

2 Optional basic use

A practical application scenario is to obtain the user’s region ID information. The traditional method is shown in Listing 2-1:

// Listing 2-1
// Get the user's locale 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 ;
}
Copy the code

A NullPointerException caused by a null object can be avoided with if-else heavy check. The same effect can be achieved with Optional functional programming, as shown in Listing 2-2:

  // Listing 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("New value cannot be obtained")).toUpperCase();
  }
Copy the code

Tips double colon: with the arrow function ->, which is a Java8 lambda expression, is the anonymous function used in listing 2-3.

 // Listing 2-3
  public  void test(a){
 
    // create a new collection
    List<String> list = new ArrayList();
    /// simulate data
    for (int i = 0; i < 10; i++) {
      list.add("Test data"+i);
    }
    

    // The first for loop
    for (int i = 0; i < list.size(); i++) {
      // Get the value of the corresponding index in the list
      String s = list.get(i);
    }


    // The second enhances for
    for (String  s: list) {
      //s is the value of the retrieved list
    }

    // The third way uses lambda expressions and the function operator ->
    list.forEach((s) -> System.out.println(s));

    // The fourth Java8 uses the double colon: : operator
    list.forEach(System.out::println);

  }
Copy the code

The effect in Listing 2-2 can also be achieved using double colons, as shown in Listing 2-4:

  // Listing 2-4
  public String getUserCountryCodByOptional2(UserInfor user) {
    return Optional.ofNullable(user)
        .map(UserInfor::getAddress)
        .map(Address::getCountry)
        .map(Country::getCountryCode)
        .orElseThrow(() -> new IllegalArgumentException("New value cannot be obtained")).toUpperCase();
  }
Copy the code

3 Optional brief description

In the above code list through the use of Optional, very elegant to achieve functional programming effect, the existing summary of the following conclusions.

3.1 Optional object Creation

When using Optional, we first create an Optional object. The two constructors of the Optional class are private, so we cannot use new Optional() to create an Optional object.

Optinal objects can be created using the three static methods empty(), of(T value), and ofNullable(T value) provided by the Optional class, as shown in the following example

    // Create an Optional object that wraps the object with an empty value
    Optional<String> optStr = Optional.empty();
    // The second creates an Optional object that wraps the object with a non-empty value
    Optional<String> optStr1 = Optional.of("optional");
    // Create a wrapper object with Optional values that are allowed to be empty
    Optional<String> optStr2 = Optional.ofNullable(null);
Copy the code

The second way is to create an Optional value for a non-null value using the of method. The of method creates the Optional class through the factory method. Note that the object cannot be passed as a null argument. If a null argument is passed in, a NullPointerException is thrown.

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

3.2 Map, flatMap, and filter

The Optional map method is used to get values from Optional, and the Optional get method is used to get values from Optional. The Optional map method is called. If Optional has a value, the value is returned by calling the mapping function. If the return value is not null, create an Optional containing the mapping return value as the map method return value, otherwise return empty Optional.

The simple description is to extract and convert values from Optional objects using the Map method.

  public void testMap(a){
    // The second creates an Optional object that wraps the object with a non-empty value
    Optional<String> optStr1 = Optional.of("Test map method data");

    /// get the value in optStr1
    Optional<String> stringOptional = optStr1.map((value) -> value);
    ///optStr1 has a value so the output is optional
    System.out.println(stringOptional.orElse("OrElse output"));
  }
Copy the code

The unit test effect is shown belowThe flatMap method is similar to the Map method except that the return value of the mapping function is different. The value returned by the mapping function of the map method can be any type T, and the mapping function of the flatMap method must be Optional. The author has not applied it to actual business scenarios.

The filter method returns Optional containing the value if it has a value and satisfies the assertion condition, otherwise returns empty Optional.

3.3 orElse, orElseGet, orElseThrow methods

The orElse method returns Optional if it has a value, otherwise it returns the specified value.

OrElseGet is similar to the orElse method except for the default value. The orElse method takes the string passed in as the default value. The orElseGet method can accept the Supplier interface implementation to generate the default value.

OrElseThrow returns a value if it has one, otherwise throws 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(a){
    // Create an Optional object that wraps the object with an empty value
    Optional<String> optStr = Optional.empty();
    //optStr has no value so output is "test orElse"
    // The orElse method takes a string
    System.out.println("Test 1"+optStr.orElse("测试 orelse  "));

    The orElseGet method receives a function method
    System.out.println("Test 2"+optStr.orElseGet(()->"Testing orElseGet"));

    The orElseGet method receives a function that returns a Throwable
    System.out.println("Test 3"+optStr.orElseThrow(()-> new IllegalArgumentException("Null")));

    // The second creates an Optional object that wraps the object with a non-empty value
    Optional<String> optStr1 = Optional.of("optional");
    ///optStr1 has a value so the output is optional
    System.out.println(optStr1.orElse("OrElse output"));
  }

Copy the code

The unit test effect is as follows:

4 other

Java 9 adds three methods for the Optional class: OR (), ifPresentOrElse(), and stream().

4.1 the or method

The or method returns the Optional value if it exists, or a default value otherwise.

4.2 the stream method

The stream method converts the Optional to a stream. If the Optional contains a value, the stream containing the value is returned. Otherwise, an empty stream is returned.

4.3 ifPresentOrElse method

In java8, the ifPresent method is used instead of the traditional if(user! = null) if (user! = null) else {// XXX}; the Optional ifPresent method in Java8 does not support else operations.

In java9, the ifPresentOrElse method is equivalent to if (user! = null) else {// XXX} operation.

public void test(UserInfor user) {
     Optional.ofNullable(user).ifPresentOrElse(u -> {
         // execute this when user is not nulluser.getName(); user.getAge(); }, () - > {// execute this when user is null
         System.err.println("User object is null");
     });
}
Copy the code