This is my 10th day of the Genwen Challenge

Based on the introduction to Java8, enhancements to Optional are available in Java9

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

1. Optional

Optional is a useful new class for Jdk1.8, which is expected to solve the annoying null judgment problem.

This class is similar to the wrapper class. The Java class to be operated on is encapsulated in the object of the class. At the same time, some common judgment logic is encapsulated as a member method.

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

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

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

  4. Judgment API: Makes some logical judgments about the value wrapped in the Optional object; 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 Optional objects:

 @Test
public void buildOptionalTest(a){
    // 1. Construct an optional object with value null;
    Optional<User> userEmptyOpt = Optional.empty();// empty the Optional object

    // create an optional object whose value cannot be null. If of() is null, the null pointer will be raised.
    //Optional
      
        userNullOpt = Optional.of(null); // NullPointerException is reported only when the attribute is not called
      
    Optional<User> userOpt = Optional.of(new User("Tang's monk"."Male".18));

    // 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, does not return empty()");
    System.out.println(userNullOpt);

}
Copy the code
Optional[User(username= tang Tang, sex= male, age=18)] Optional ofNullable, There is no return empty() optional. emptyCopy 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 is reported
    User user01 = userOpt.get();

    // orElse can pass an object of type User as the default;
    / / when the value! If =null, return value.
    // If 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 differs from orElse in that orElseGet can pass a lambda expression;
    / / when the value! If =null, return value.
    // When value==null, use the object returned by the lambda as the default;
    User user04 =  Optional.ofNullable(temp).orElseGet(()->getRandomUser(new Random().nextInt(3)));

    // orElseThrow can pass a lambda expression, which returns an Exception;
    / / when the value! If =null, return value.
    // If value==null, this exception is thrown;
    //User user05= option.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= Wukong, sex= male, age=18) User(username= Wukong, sex= male, age=20) User(username= Bajie, sex= male, age=22) User(username= Hejiong, 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));
    // Map converts the value of User to Optional
      
    Optional<String> userName = userOpt.map(User::getUsername);
    System.out.println(userName);
    System.out.println(userName.get());

    // If the input parameter of a map is also Optional, the map will form an Optional
      
       > nested structure.
      
    // But flatMap can flatten this nesting structure;
    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 a Boolean; False: returns an empty optional value.
    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 is used to check whether value is null; We must call isPresent before we call get, because if value is null, calling get directly will raise 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, nothing is done;
    user01.ifPresent(value -> System.out.println("optional value:" + value));
    user01.ifPresent(System.out::println);

}
Copy the code
Optional[User(username= dehua, sex= male, age=18)] Optional. Empty Optional value==null Optional value:User(username= dehua, age=18) Sex = male, age=18) username= dehua, sex= male, age=18Copy the code

5. Method description

methods describe
empty Returns an empty Optional object
of Returns the specified value wrapped with Optional, or throws a NullPointException if the value is null
ofNullable Returns the specified value wrapped with Optional, or an empty Optional object if the value is null
get Returns the value Optional wrapped if it exists, otherwise throws a NoSuchElementException
orElse If there is a value, it is returned, otherwise a default value is returned
orElseGet Returns a value if there is one, otherwise returns a value generated by the specified Supplier interface
orElseThrow Returns a value if it exists, otherwise throws an exception generated by the specified Supplier interface
map If the value exists, the provided mapping method is called on that value
flatMap If the value exists, the provided mapping method is called on the value and returns the value of an Optional class, otherwise an empty Optional object is returned
filter Returns the Optional object containing the value if it exists and satisfies the provided predicate (condition), otherwise returns an empty Optional object
isPresent Return true if it exists, false otherwise
ifPresent If the value exists, execute the method call using that value, otherwise do nothing

(1) The flatMap method has the same function as the map method

Function returns an Optional instance, and the flatMap method returns the result directly, without wrapping the result in a layer of Optional values. Multiple Optional merges are possible.

The appendix

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

When an entity is queried, it is returned if the corresponding record exists in the database, and 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) Repeated 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

Select * from user where user = 0;

// 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 collection, I use this method a lot, very cool

Traditional way: Lots of 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