This is the 15th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

Based on the introduction of Java8, in Java9 to the Optional enhancement

Reference: www.wdbyte.com/2019/11/jdk…

1. Optional

Optional is a new class provided by Jdk1.8. We hope to solve the problem of null judgment by introducing this class.

This class is similar to a wrapper class. It encapsulates the Java class to be operated inside the object of the class, and encapsulates some commonly used judgment logic into member methods. Combined with lambda syntax, it achieves elegant chained calls.

  1. Build the API: Build an Optional object; Empty (), of(), ofNullable()

  2. Get the API: Get the value wrapped in the Optional object; Methods are: get(), orElse(), orElseGet(), orElseThrow()

  3. Conversion API: converts the value wrapped in the Optional object to a new value. Methods: map(), flatMap()

  4. Apis for determining the values wrapped in Optional objects Methods: filter(), isPresent(), ifPresent()

2. Build a class

Simply prepare a Java class

package com.hanpang.model;
import lombok.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class User {
    private String username;
    private String sex;
    private Integer age;
}
Copy the code

Create an Optional object.

 @Test
public void buildOptionalTest(a){
    // 1. Create an optional object whose value is null;
    Optional<User> userEmptyOpt = Optional.empty();// "Empty" Optional

    // 2. Create an optional object whose value cannot be null. If the input parameter of() is null, a null pointer exception is reported.
    //Optional
      
        userNullOpt = Optional.of(null); // A NullPointerException is reported when the property is not called
      
    Optional<User> userOpt = Optional.of(new User("Tang's monk"."Male".18));

    // 3. Create an optional object whose value can be null
    Optional<User> userNullOpt = Optional.ofNullable(null);

    System.out.println("Optional empty object");
    System.out.println(userEmptyOpt);

    System.out.println("Optional of object must exist, otherwise null pointer exception");
    System.out.println(userOpt);

    System.out.println("Optional ofNullable, returns Empty () if it does not exist");
    System.out.println(userNullOpt);

}
Copy the code
Optional[User(User = Username, sex= male, age=18)] Optional ofNullable, Empty () Optional. Empty does not existCopy the code

3. Access to class

 @Test
public void getOptionalTest(a){
    Optional<User> userEmptyOpt = Optional.empty();

    Optional<User> userOpt = Optional.of(new User("Tang's monk"."Male".18));

    If value==null, NoSuchElementException will be reported
    User user01 = userOpt.get();

    // orElse can pass in an object of type User as the default value;
    / / when the value! =null, return value;
    // When value==null, return the default value instead;
    User user02 = userEmptyOpt.orElse(new User("The wu is empty"."Male".20));

    User temp = null; / / Optional. OfNullable (temp) returns Optional. Empty ()
    User user03 =  Optional.ofNullable(temp).orElse(new User("Eight quit"."Male".22));

    // orElseGet is different from orElse in that orElseGet can be passed a lambda expression;
    / / when the value! =null, return value;
    // When value==null, the object returned by the lambda is used as the default value;
    User user04 =  Optional.ofNullable(temp).orElseGet(()->getRandomUser(new Random().nextInt(3)));

    // orElseThrow can pass in a lambda expression that returns an Exception;
    / / when the value! =null, return value;
    // Throw this exception when value==null;
    //User user05= Optional. OfNullable (temp).orelseThrow (()->new RuntimeException(" object does not exist "));
    //User user06= Optional.ofNullable(temp).orElseThrow(NullPointerException::new); // Method reference

    System.out.println(user01);
    System.out.println(user02);
    System.out.println(user03);
    System.out.println(user04);

}
private User getRandomUser(int index){
    ArrayList<User> users = new ArrayList<>();
    users.add(new User("Peng Yuchang"."Male".24));
    users.add(new User("Zhang Zifeng"."Female".20));
    users.add(new User(Ajit ""."Male".44));
    return users.get(index);
}
Copy the code
User(username= 9, age=18) User(username= 9, age=18) User(username= 9, age=18) Sex = male, age = 44)Copy the code

3. The transformation class

@Test
public void mapOptionalValueTest(a){
    Optional<User> userOpt = Optional.of(new User("hanpang"."Male".18));
    // Select value from User where value is Optional
      
    Optional<String> userName = userOpt.map(User::getUsername);
    System.out.println(userName);
    System.out.println(userName.get());

    // Map 
      
       >; // Map 
       
        >;
       
    // But the flatMap can make the nested structure even;
    Optional<Optional<String>> unFlatMap = userOpt.map(user->Optional.of(user.getUsername()));
    System.out.println(unFlatMap);
    Optional<String> flatMap  = userOpt.flatMap(user->Optional.of(user.getUsername()));
    System.out.println(flatMap);
}
Copy the code
Optional[hanpang]
hanpang
Optional[Optional[hanpang]]
Optional[hanpang]
Copy the code

4. The judge class

@Test
public void judgeOptionalValueTest(a){
    Optional<User> userOpt = Optional.of(new User("Andy Lau"."Male".18));

    // Filter passes a lambda, which returns Boolean; False: returns an empty optional;
    Optional<User> user01 = userOpt.filter(user->user.getAge()<20);
    System.out.println(user01);

    Optional<User> user02 = userOpt.filter(user->user.getAge()>20);
    System.out.println(user02);

    // isPresent = null; We have to call isPresent before we call GET, because if we call get directly, if value is null, then we'll get an exception.
    User user = null;
    Optional<User> userOptional = Optional.ofNullable(user);
    if(userOptional.isPresent()){
        User u1 = userOptional.get();
        System.out.println("Object exists");
    }else{
        System.out.println("optional value==null");
    }

    // ifPresent passes a lambda when value! =null, execute the logic inside; When value==null, do nothing;
    user01.ifPresent(value -> System.out.println("optional value:" + value));
    user01.ifPresent(System.out::println);

}
Copy the code
Username ==null Optional value:User(username= username, age=18) Username = username, username= username, age=18)Copy the code

5. Method description

methods describe
empty Return an empty Optional object
of Returns the specified value wrapped in Optional. If the value is null, a NullPointException is thrown
ofNullable Return the specified value wrapped in Optional. If null, an empty Optional object is returned
get If the value exists, return it as Optional, otherwise a NoSuchElementException is thrown
orElse Return a value if there is one, otherwise return a default value
orElseGet Returns a value if any, otherwise returns a value generated by the specified Supplier interface
orElseThrow Returns a value if any, or throws an exception generated by the specified Supplier interface
map If the value exists, the provided mapping method is called to the value
flatMap If the value exists, the provided mapping method is called to the value, returning an Optional value. Otherwise, an empty Optional object is returned
filter Return the Optional object containing the value if it exists and satisfies the supplied predicate (condition), otherwise an empty Optional object is returned
isPresent Return true if it exists, false otherwise
ifPresent If the value exists, do the method call that uses that value, otherwise do nothing

(1) The flatMap method is consistent with the MAP method

However, the Function that flatMap accepts requires an Optional instance to be returned, and the flatMap method returns the result without wrapping the result in an Optional instance. Multiple Optional layers can be merged.

The appendix

(1)orElseThrowIn the SpringMVC controller, we can configure to handle all kinds of exceptions uniformly.

When querying an entity, the record is returned if it exists in the database, or it can be thrown otherwise

@RequestMapping("/{id}")
public User getUser(@PathVariable Integer id) {
    Optional<User> user = userService.getUserById(id);
    return user.orElseThrow(() -> new EntityNotFoundException("Id" + id + "User does not exist"));
}

@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<String> handleException(EntityNotFoundException ex) {
    return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
Copy the code

(2) Multiple usemapoperation

@Test
public void moreMapTest(a){
    User user = new User("han#pang"."Male".18);
    Optional<String> name = Optional
        .ofNullable(user)
        .map(u -> u.getUsername())
        .map(username -> username.toUpperCase())
        .map(username -> username.replace(The '#'.' '));
    System.out.println(name);
    System.out.println(name.get());
}
Copy the code
Optional[HAN PANG]
HAN PANG
Copy the code

(3) Find the length of the string user (return 0 if null)

// Get the input user information from the foreground interface
String user = getUserFromUI();
return Optional.ofNullable(user).orElse("").length;
Copy the code

(4) Loop through the set. I use this a lot. It’s nice

Traditional: more code

List<String> userList = getList();
if(list ! =null) {
  for(String user: list){ System.out.println(user); }}Copy the code

Code to improve

List<String> userList = getList();
Optional.ofNullable(userList).orElse(new ArrayList<>()).forEach(user -> {
    System.out.println(user);
});
Copy the code