It’s Optional
1. Introduction
Java (NPE) Null Pointer Exception (NPE) Null Pointer Exception (NPE) We are going to use the new Java8 feature Optional to simplify code as much as possible and efficiently handle NPE (Null Pointer Exception)
2. Meet Optional and use it
In simple terms, Opitonal class is provided by Java in order to solve the problem of determining whether an object is empty will use null! =obj (Null Pointer Exception) = obJ (Null Pointer Exception) = OBJ (Null Pointer Exception)
General judgment:/ / object
// Attributes are name, age
Person person=new Person();
if (null==person){
return "The person is null";
}
return person;
Copy the code
Optional:/ / object
// Attributes are name, age
Person person=new Person();
return Optional.ofNullable(person).orElse("The person is null");
Copy the code
The test shows the Class Person code (take a look at this if you don’t understand) :
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Person(a) {}public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge(a) {
return age;
}
public void setAge(Integer age) {
this.age = age; }}Copy the code
Below, we will learn about the magical Optional class efficiently!
2.1 Optional object Creation
So let’s go inside Optional and take a look at some of the ways that we can create Optional objects
public final class Optional<T> {
private static finalOptional<? > EMPTY =new Optional<>();
private final T value;
// We can see that both construction squares are private
// We can't create Optional objects outside
private Optional(a) {
this.value = null;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
// This static method basically creates an object whose wrapper value is empty because there are no arguments assigned
public static<T> Optional<T> empty(a) {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
// This static method basically creates an object with a wrapper value that is not empty because of the assignment
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
// This static method basically creates an empty object if the argument value is null, and a parameterized object if it is not
public static <T> Optional<T> ofNullable(T value) {
return value == null? empty() : of(value); }}Copy the code
Do a simple example to show the corresponding above
// create an Optional object that wraps the object with an empty value
Optional<String> optEmpty = Optional.empty();
// create an Optional object that wraps the object with a non-empty value
Optional<String> optOf = Optional.of("optional");
// create an Optional wrapper object whose value can be empty or non-empty
Optional<String> optOfNullable1 = Optional.ofNullable(null);
Optional<String> optOfNullable2 = Optional.ofNullable("optional");
Copy the code
Now that we’ve done an overview of the internal methods for creating Optional objects, we’re going to start looking at Optional
2.2 optional.get () method (returns the value of the object)
The get() method returns an instance value of an option.
public T get(a) {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
Copy the code
That is, if value is not null, return, if value is null, throw an exception “No value present” example
Person person=new Person();
person.setAge(2);
Optional.ofNullable(person).get();
Copy the code
2.3 Option.isPresent () (null)
The isPresent() method returns a Boolean value, true if the object is not empty, false if it is empty.
public boolean isPresent(a) {
returnvalue ! =null;
}
Copy the code
A simple example shows:
Person person=new Person();
person.setAge(2);
if (Optional.ofNullable(person).isPresent()){
// Write non-null logic
System.out.println("Not empty");
}else{
// Write to empty logic
System.out.println("Empty");
}
Copy the code
2.4 optional.ifPresent () method (reads null and returns function)
If the object is not empty, run the function body.
public void ifPresent(Consumer<? super T> consumer) {
// If value is not null, the accept body is run
if(value ! =null)
consumer.accept(value);
}
Copy the code
See instances:
Person person=new Person();
person.setAge(2);
Optional.ofNullable(person).ifPresent(p -> System.out.println("Age"+p.getAge()));
Copy the code
If the object is not empty, the age is printed, because NPE has already been done internally, so you don’t have to worry about null-pointer exceptions
2.5 optional.filter () method (filter objects)
The filter() method basically means that we take an object and filter it with criteria, returning the Optional object itself if the criteria are met, and empty Optional if not.
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
// Return this if null
if(! isPresent())return this;
else
// Check whether the return itself is empty Optional
return predicate.test(value) ? this : empty();
}
Copy the code
A simple example:
Person person=new Person();
person.setAge(2);
Optional.ofNullable(person).filter(p -> p.getAge()>50);
Copy the code
2.6 optional.map () method (re-wrap the object)
The map() method performs a quadratic operation on an object corresponding to the Funcation interface, encapsulates it into a new object and returns it in Optional:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
// Return itself if null
if(! isPresent())return empty();
else {
// Otherwise return Optional decorated with the method
returnOptional.ofNullable(mapper.apply(value)); }}Copy the code
Examples show:
Person person1=new Person();
person.setAge(2);
String optName = Optional.ofNullable(person).map(p -> person.getName()).orElse("The name is empty." ");
Copy the code
2.7 optional.flatmap () method (Optional object for secondary wrapping)
The map() method performs a secondary operation on the object corresponding to the Optional< Funcation > function interface, encapsulates it into a new object and returns it in Optional:
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if(! isPresent())return empty();
else {
returnObjects.requireNonNull(mapper.apply(value)); }}Copy the code
Example:
Person person=new Person();
person.setAge(2);
Optional<Object> optName = Optional.ofNullable(person).map(p -> Optional.ofNullable(p.getName()).orElse("The name is empty." "));
Copy the code
2.8 optional.orelse () method (returns an object with nothing)
If the object is empty, execute the value of the orElse method. If the object is not empty, return the source code of the write object.
public T orElse(T other) {
// If not empty, return value, if empty, return other
returnvalue ! =null ? value : other;
}
Copy the code
Example:
Person person1=new Person();
person.setAge(2);
Optional.ofNullable(person).orElse(new Person("Xiao Ming".2));
Copy the code
2.9 optional. orElseGet() method (returns the Supplier object with nothing)
This is similar to orElse, except that the input parameter is the Supplier object, which is empty and returns the. Get () method of the passed object, or the current object if it is not empty:
public T orElseGet(Supplier<? extends T> other) {
returnvalue ! =null ? value : other.get();
}
Copy the code
Example:
Optional<Supplier<Person>> sup=Optional.ofNullable(Person::new);
// Call the get() method, at which point the constructor of the object is called, i.e. the real object is obtained
Optional.ofNullable(person).orElseGet(sup.get());
Copy the code
To be honest, I was confused about the Supplier object as well. I looked it up online and found that Supplier is also a way to create an object. In short, Suppiler is an interface that is lazy like Spring and does not take up memory once declared. The syntax for creating an object is Supplier
2.10 optional. orElseThrow() method (return exception if null)
This I personally in the actual practice also often use this method, method function is if empty, throw you define the exception, if not empty to return the current object, in the actual practice all exceptions must be handled well, for the readability of the code source:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if(value ! =null) {
return value;
} else {
throwexceptionSupplier.get(); }}Copy the code
Example: This post actual combat source code
// A simple query
Member member = memberService.selectByPhone(request.getPhone());
Optional.ofNullable(member).orElseThrow(() -> new ServiceException("No query related data"));
Copy the code
2.11 Comparative analysis of similarity methods
OrElse () is similar to orElseGet() and orElseThrow(). Map() is similar to flatMap(). So let me just summarize for you the similarities and differences between different methods orElse() and orElseGet() and orElseThrow()
OrElse (T object) orElseGet (Supplier < T > object) orElseThrow (exception)
Similarities and differences between Map () and orElseGet
Map (function function) flatmap (Optional< function > function)
How can I use the magic Optional option in real life
3. Actual combat scene reproduction
Scenario 1: Query an object in the Service layer, return it, determine whether it is empty, and process it
// Query an object
Member member = memberService.selectByIdNo(request.getCertificateNo());
// use ofNullable and orElseThrow to judge and manipulate
Optional.ofNullable(member).orElseThrow(() -> new ServiceException("No query related data"));
Copy the code
Scenario 2: We can define the return value in the DAO interface layer with Optional. For example: I use JPA, and so on
public interface LocationRepository extends JpaRepository<Location.String> {
Optional<Location> findLocationById(String id);
}
Copy the code
But in Service
public TerminalVO findById(String id) {
// This method is also wrapped Optional in the DAO layer
Optional<Terminal> terminalOptional = terminalRepository.findById(id);
// Use isPresent() directly to check whether isPresent() is null
if (terminalOptional.isPresent()) {
// Use the get() method to get the object value
Terminal terminal = terminalOptional.get();
// We can use BeanCopy instead of set to assign values
TerminalVO terminalVO = BeanCopyUtils.copyBean(terminal, TerminalVO.class);
// Call the DAO layer method to return the wrapped object
Optional<Location> location = locationRepository.findLocationById(terminal.getLocationId());
if (location.isPresent()) {
terminalVO.setFullName(location.get().getFullName());
}
return terminalVO;
}
// Don't forget to throw an exception
throw new ServiceException("This terminal does not exist");
}
Copy the code
There are many more scenarios, including whether to return the current value or jump to another method body, and many more. If you are not experienced friends still want to learn, you can comment on it and I will reply to you
4.Optional use
Can Optional completely replace if? Example 1: What if I just want to determine whether a variable of an object is empty and make that determination?
Person person=new Person();
person.setName("");
persion.setAge(2);
// Common judgment
if(StringUtils.isNotBlank(person.getName())){
// Execute code block with non-empty name
}
// Use Optional
Optional.ofNullable(person).map(p -> p.getName()).orElse("The name is empty." ");
Copy the code
I think this is a good example, but it’s a very simple judgment, if you use Optional you need to think about wrapping values, you need to think about code writing, you need to think about method calls, it’s only one line, but it’s not very readable, and if another programmer reads it, it’s not as obvious as if
5. Jdk1.9 optimized for Optional
Three methods were first added: OR (), ifPresentOrElse(), and stream(). Or () is similar to methods such as orElse in that it returns an object if it is not empty, or the default value in the or() method if it is empty. The ifPresentOrElse() method takes two arguments: a Consumer and a Runnable. If the object is not empty, the action Consumer is performed, otherwise Runnable is run. There are more OrElse judgments than ifPresent (). **stream()** Converts Optional to stream, returning a stream containing the value if there is a value, and an empty stream if there is no value.
Because this JDK1.9 Optional specific I did not test, but also found that there is a pretty good article has also let you understand jdK1.9 option optimization, I will not go into the details.
The author’s words
Mutual respect, mutual progress, thank you very much for everyone’s selfless spirit. Only in this way can we make more and more progress in IT in China. We are also willing to listen to the opinions and suggestions of more leaders with an open mind. I am your good friend Fan Yifan
If you think it’s good, I hope you can give me a thumbs up. Thank you very much! I want to make friends with you and make progress with you! A programmer who gets a little better every day