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.
-
Build the API: Build an Optional object; Empty (), of(), ofNullable()
-
Get the API: Get the value wrapped in the Optional object; Methods are: get(), orElse(), orElseGet(), orElseThrow()
-
Conversion API: converts the value wrapped in the Optional object to a new value. Methods: map(), flatMap()
-
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)orElseThrow
In 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 usemap
operation
@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