I. Replace NULL with optional
1. Optional class
Java.util.optional<t> is a class that encapsulates Optional values.
When a variable is present, the optional class simply encapsulates the class. When a variable does not exist, the missing value is modeled as an "empty" optional object, returned by Method Optional.empty ().
The Optional.empty () method is a static factory method that returns a specific single instance of the Optional class.
a very important and practical semantic difference between using optional instead of NULL:
declaring a variable using optional<t> instead of a specific object, this statement is very clear that the loss of the occurrence of the variable here is allowed.
2. Several modes of applying optional
Create a optional object
--declaration of an empty optional
optional<car> Optcar = Optional.empty ();
--Create optional based on a non-null value
optional<car> Optcar = Optional.of (Car); If car is a null, this code throws nullpointexception immediately instead of waiting for an error to be returned when trying to access the property value of car.
--acceptable null optional (used when implementing a serialized domain model)
optional<car> Optcar = optional.ofnullable (Car); Creates a optional object that allows null values, and if car is null, then the resulting optional object is an empty object
extracting and converting values from a optional object using map
public class Person {//someone has a car, someone does not have a car private optional<car> cars; Public optional<car> Getcar () {return Car;}}
public class Car {//Some cars have insurance, some cars have no insurance private optional<insurance> Insurance; Public optional<insurance> getinsurance () {return Insurance;}}
public class Insurance {//insurance company must have a name, if there is an insurance company without a name is an error case private String name; Public String GetName () {return name;}}
optional<insurance> optinsurance = optional.ofnullable (Insurance);optional<string> name = Optinsurance.map (Insurance::getname)
optional objects with flatmap links
When using a stream, the Flatmap method takes a function as an argument, and the return value of the function is another stream. This method is applied to each function in the stream, resulting in the flow of a new stream. However, Flatmap replaces each newly generated stream with the contents of the stream. That is, each stream generated by the method is merged or flattened into a single stream.
optional<person> optperson = optional.of (person); Optional<String> name = optperson.map (Person::getCar) .map (Car::getInsurance) //Error code &NBSP;&NBSP;&NBSP; .map (Insurance::getName)
Getcar returns an object of type optional<car>, so the first map gets the result optional<optional<car>> ; the object of type. So his call to getinsurance is illegal. The Getinsurance method is not supported.
Using Flatmap, the optional of the two-layered structure is a single-layer structure with car.
Optional<String> name = optperson.flatmap (Person::getCar ) .flatmap (Car:: Getinsurance) .map (Insurance::getName) .orelse ("Unknown"); // If the optional result is empty, set the default value
default behavior and dereference optional objects
-Get () is the simplest and least secure method of these methods . If there is a variable, he directly returns the value of the encapsulated variable, otherwise throws nosuchelementexception;
--OrElse (T Other) allows you to provide a default value when the optional object does not contain a value;
--Orelseget (supplier< extends t> other) is a deferred call version of the OrElse method, Supplier method only in Optiona The call is executed only if the object does not contain a value. If creating a default value is a time-consuming effort, you should take it this way, or you need to be very sure that a method is called only when optional is empty, or you can consider the method (which has strict constraints);
--Orelsethrow (supplier<? extends x> Exceptionalsupplier) is very similar to the Get method when optional Throws an exception when the object is empty, but using Orelsethrow you can customize the exception you want to throw;
--Ifpresent (consumer< Super t>) allows you to execute a method passed in as a parameter when the value of the variable exists, otherwise no action is taken.
Two combination of optional objects
Public optional<insurance> nullsafefindcheapestinsurance (optional<person> person, Optional<Car> Car) {return Person.flatmap (P-Car.map (C-Findcheapestinsurance (P, c));}
use filter to reject specific values
Find the list of insurers for the person older than or equal to the Minage parameter public String getcarinsurancename (optional<person> person, int minage) { Return Person.filter (P-p.getage () >= minage). FlatMap (Person::getcar). FlatMap (Car::getinsurance) . Map (Insurance::getname). OrElse ("Unknown");}
There are many similar methods for optional and stream interfaces .
methods of the optional class
Method |
Describe |
Empty |
Returns an empty instance of optional |
Filter |
If the value exists and satisfies the provided predicate, the optional object containing the value is returned, otherwise an empty optional object is returned |
FlatMap |
If the value exists, the provided mapping function call is performed on the value, returning a value of type optional, otherwise returning an empty optional object |
Get |
If the value exists, it will be returned by the optional encapsulated value, or a Nosunchelementexception exception is thrown |
Ifpresent |
If a value exists, execute a method call that uses that value, or do nothing |
IsPresent |
Returns True if the value exists, otherwise false |
Map |
If the value exists, the provided mapping function call is provided for the value execution |
Of |
Returns the specified value after encapsulation with optional, or throws a Nullpointexception exception if the value is null |
Ofnullable |
Returns the specified value after encapsulation with optional, or returns an empty optional object if the value is null |
OrElse |
Returns a value if it is available, otherwise returns a default value |
Orelseget |
Returns a value if it is available, or returns a value generated by the specified supplier interface |
Orelsethrow |
Returns a value if it is returned, or throws an exception that is generated by the specified supplier interface |
New features of Java8: Optional