background
In the normal development process, when an object is used, the judgment of NullPointerException will be advanced. Only when the object is not empty can the attribute value of the object be obtained, otherwise NullPointerException (NPE) will be reported. Therefore, in order to solve the NullPointerException problem, reduce NullPointerException in the code. Java8 introduces a new Optional class.
introduce
-
The Optional class is a container object that can be null. The isPresent() method returns true if the value exists, and calling the get() method returns the object.
-
Optional is a container: it can hold values of type T, or just NULL. Optional provides a number of useful methods so that we don’t have to explicitly null-check.
-
The Optional class is a good solution to null-pointer exceptions.
What does it look like? The following
public String result(User user) {
String result = Optional.ofNullable(user)
.map(User::getSchool)
.map(School::getClass)
.map(Class::getName)
.orElse("null");
return result;
}
Copy the code
API
1. Create an Optional instance
Optional, empty, of, ofNullabe
- Optional: the constructor, as you can see, is private, i.e. cannot be called from outside.
private static finalOptional<? > EMPTY =new Optional<>();
Copy the code
- Empty: Returns an empty Optional object
public static<T> Optional<T> empty(a) {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
Copy the code
- Of: Creates an Optional value for non-null values.
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
Copy the code
- OfNullable: Returns the specified value described in Optional if it is not null, otherwise returns empty Optional.
Source:public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
使用
Optional<User> opt = Optional.ofNullable(user);
Copy the code
OfNullabe = ofNullabe
When value is null, of raises a null pointer exception, and ofNullabe returns an empty optional
2. Obtain the value of the optional object
Get: Returns Optional if it has a value, otherwise throws NoSuchElementException, so null is required before using it
Source:public T get(a) {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
使用:
User user = Optional.get();
Copy the code
Note: Avoid Optional. Get (). Never call get () if you can’t prove that it has a value
3. Determine whether it exists
IsPresent () and ifPresent (Consumer <? super T> consumer)
- IsPresent () : The method returns true if the value exists, false otherwise
Public Boolean isPresent() {return value! = null; } use: if (opt.ispresent () {//do something}Copy the code
- ifPresent(Consumer
consumer) : calls consumer with the value if it exists, otherwise nothing is done.
Public void ifPresent(Consumer<? super T> consumer) { if (value ! = null) consumer.accept(value); } use optional. IfPresent (s -> {//do something});Copy the code
4. Return to the default value
Other orElse (T), orElseGet: Supplier <? Extends T> other) and orElseThrow(Supplier<? extends X> exceptionSupplier)
- OrElse: returns a value if there is one, otherwise returns another value specified
Public T orElse(T other) {return value! = null ? value : other; } use User User = option.offnullable (User).orelse (createUser());Copy the code
- OrElseGet: Returns the value if it exists, otherwise fires Other and returns the result of the other call
Public T orElseGet(Supplier<? extends T> other) { return value ! = null ? value : other.get(); } use User User = option.offnullable (User).orelseget (createUser());Copy the code
The real difference is that orElse fires the createUser() method regardless of whether the optional object is empty. OrElseGet will only trigger createUser() if it is empty.
- OrElseThrow: Returns the contained value if it exists, otherwise throws an exception inherited by the Supplier
Public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { if (value ! = null) { return value; } else { throw exceptionSupplier.get(); }} use optional.ofnullable (user).orelsethrow (()->new Exception(" user null "));Copy the code
5. Conversion value
map(Function<? super T, ? Extends U> mapper) and flatMap(Function<? super T, Optional<U>> mapper)
- Map: If there is a value, the call to the mapping function returns the value, otherwise empty Optional is returned.
The source codepublic<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if(! isPresent())return empty();
else {
returnOptional.ofNullable(mapper.apply(value)); }} use optional.ofnullable (user).map(u-> u.getName());Copy the code
- FlatMap: Returns the value of the mapping method based on the Optional inclusion if the value exists, otherwise returns an empty Optional
Optional.ofNullable(user).map(u-> u.getName()); Public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { Objects.requireNonNull(mapper); if (! isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); }} use option.ofnullable ((user).map(u-> option.ofnullable (u.getName());Copy the code
Difference: The difference between a flatMap and a Map is that the parameters received are different.
6. The filter value
filter(Predicate<? super predicate)
If the value exists and matches the given predicate, return an Optional that describes the value, otherwise return an empty Optional
Public Optional<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); if (! isPresent()) return this; else return predicate.test(value) ? this : empty(); Optional optional <User> opt = option.ofnullable (User).filter(u -> u.getName()! = null);Copy the code
conclusion
Optional is used to resolve null pointer exceptions, but it can’t be used overnight. Some simple code can do this
With Optional, the code is more elegant, but less logical and less readable.
So do not abuse, use as appropriate. For example, you can use optional as the return type when the return value is uncertain.
Concern public number: Zhen Shrimp, share more Java dry goods