Use Java 8 ’s new feature Optional instead of if-else to solve the null pointer problem
static constructor
JDK provides three static methods to construct an `Optional`
-
public
final
class
Optional<T> {
-
-
private
static
final Optional<?> EMPTY =
new
Optional<>();
-
private
final T value;
-
-
// This method is used to construct an empty Optional. If the value in the Optional is null, the Optional will not contain a value.
-
public
static<T> Optional<T>
empty
() {
-
@SuppressWarnings("unchecked")
-
Optional<T> t = (Optional<T>) EMPTY;
-
return t;
-
}
-
-
//Construct an Optional through a non-null value,
-
//The returned Optional contains the value value. For this method, the parameters passed in must not be null, otherwise NullPointerException will be thrown.
-
public
static <T> Optional<T>
of
(T value) {
-
return
new
Optional<>(value);
-
}
-
-
//The difference between this method and of method is that the parameter passed in can be null. If it is null, Optional.empty() is returned.
-
public
static <T> Optional<T>
ofNullable
(T value) {
-
return value ==
null ? empty() : of(value);
-
}
-
}
Common methods
isPresent() / ifPresent()
-
// Return true if the value exists, false otherwise
-
public
boolean
isPresent
() {
-
return value !=
null;
-
}
-
-
// If the Optional instance has a value, call consumer for it, otherwise no processing will be done.
-
public
void
ifPresent
(Consumer<? super T> consumer) {
-
if (value !=
null)
-
consumer.accept(value);
-
}
test
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
User
user
=
new
User();
-
Optional<User> optional = Optional.ofNullable(user);
-
optional.ifPresent(s -> System.out.println(s));
-
}
-
}
Get()
Get the value in Optional, which is our value. Optional is equivalent to a shell.
-
public T
get
() {
-
if (value ==
null) {
-
throw
new
NoSuchElementException(
"No value present");
-
}
-
return value;
-
}
orElse() / orElseGet() / orElseThrow()
-
// If the value in Optional is not empty, return the value in Optional. If it is empty, return the other value.
-
public T
orElse
(T other) {
-
return value !=
null ? value : other;
-
}
-
-
// If there is a value in Optional, return the value, otherwise return the result of other call
-
public T
orElseGet
(Supplier<? extends T> other) {
-
return value !=
null ? value : other.get();
-
}
-
-
// If the value in Optional exists, the value is returned. If the value does not exist, the exception in the exception function Supplier is thrown.
-
public <X
extends
Throwable> T
orElseThrow
(Supplier<? extends X> exceptionSupplier)
throws X {
-
if (value !=
null) {
-
return value;
-
}
else {
-
throw exceptionSupplier.get();
-
}
-
}
test
-
String
value
=
"2";
-
String
orElse
= Optional.ofNullable(value).orElse(
"1");
-
System.out.println(orElse);
//2
-
-
String
value
=
null;
-
String
orElse
= Optional.ofNullable(value).orElse(
"1");
-
System.out.println(orElse);
//1
-
-
-------------------------------------------------------
-
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
String
value
=
null;
-
String
orElse
= Optional.ofNullable(value).orElseGet(OptionalTest::get);
-
System.out.println(orElse);
// 123
-
-
String
value
=
"2";
-
String
orElse
=
Optional.ofNullable(value).orElseGet(OptionalTest::get);
-
System.out.println(orElse);
// 2
-
}
-
-
public
static String
get
(){
-
return
"123";
-
}
-
}
-
-
-------------------------------------------------------
-
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
String
value
=
null;
-
String
orElse
=
Optional.ofNullable(value).orElseThrow(() -> new RuntimeException ( "Value does not exist" ));
-
System.out.println(orElse);
-
}
-
}
map() / flatMap()
-
map(Function)
: If Optional is not empty, apply Function to the content in Optional and return the result. Otherwise, Optional.empty is returned directly . -
flatMap(Function)
:Samemap()
, but the provided mapping function wraps the result in an Optional object, soflatMap()
no wrapping is done at the end.
None of the above methods are applicable to numeric Optional . Generally speaking, streams filter()
will remove stream elements when Predicate returns . The Optionalfalse
will not Optional.filter()
be deleted on failure , but will be retained and converted to empty.
-
// Pass the value in Optional as a parameter to map. If the value passed in is empty, an empty Optional object is returned, which is equivalent to Optional.empty(),
-
// If it is not empty, we can return a return value that can describe the result (the value in Optional, this value can be reassigned)
-
public<U> Optional<U>
map
(Function<? super T, ? extends U> mapper) {
-
Objects.requireNonNull(mapper);
-
if (!isPresent())
-
return empty();
-
else {
-
return Optional.ofNullable(mapper.apply(value));
-
}
-
}
-
-
// If the value in Optional exists, then return a value based on Optional (such as Optional),
-
// If the value in Optional does not exist, an empty Optional object is returned, equivalent to Optional.empty(),
-
// Unlike map, map returns a value, while flatMap returns a value based on Optional
-
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));
-
}
-
}
test
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
User
user
=
null;
-
Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
-
System.out.println(optional);
//Optional.empty
-
-
User
user
=
new
User();
-
user.setUsername(
"Admin");
-
Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
-
System.out.println(optional);
// Optional[Admin]
-
-
}
-
-
public
static String
getMap
(User user){
-
return user.getUsername();
-
}
-
-
-------------------------------------------------------
-
-
User
user
=
new
User();
-
user.setUsername(
"Admin");
-
Optional<String> optional = Optional.ofNullable(user).flatMap(OptionalTest::getFlatMap);
-
System.out.println(optional);
-
}
-
public
static Optional<String>
getFlatMap
(User user){
-
return Optional.ofNullable(user).map(User::getUsername);
-
}
-
filter()
Pass the value in Optional as a parameter. If it meets the rules, an Optional object is returned, otherwise an empty Optional object (Optional.empty) is returned.
-
public Optional<T>
filter
(Predicate<? super T> predicate) {
-
Objects.requireNonNull(predicate);
-
if (!isPresent())
-
return
this;
-
else
-
return predicate.test(value) ?
this : empty();
-
}
Actual combat
ifPresent(), this is a terminal operation. If the value exists, the specified consumption method will be called.
-
// Get the value of book, if book is null, return the default value
-
String
book
= Optional.ofNullable(person).map(Person::getBook).orElse(
"default");
-
-
// If person is not null, print salary
-
Optional.ofNullable(person).ifPresent(p -> System.out.println(p.getSalary()));
-
-
// If book is null, set the default value
-
Optional.ofNullable(person)
-
.map(Person::getComputer)
-
.ifPresent(c -> c.setBrandName(
"default name"));
-
-
Optional.ofNullable(person)
-
.map(Person::getComputer)
-
.ifPresent(
this::consumerTest);
-
-
public
void
consumerTest
(Computer computer){
-
System.out.println(
"consumer test");
-
System.out.println(computer);
-
}
-
-
// Get brand, if brandName is "", throw an exception
-
// Because map can only filter out null values, and we usually need to make other judgments at work, we can use map to parse a certain attribute in the entity class, and then use filter to perform corresponding filtering.
-
String
brand
= Optional.ofNullable(person)
-
.map(Person::getComputer)
-
.map(Computer::getBrandName)
-
.filter(b -> !b.equals(
""))
-
.orElseThrow(() -> new NumberFormatException ( "Brand is empty" ));
-
System.out.println(
"brand: " + brand);
Use Java 8 ’s new feature Optional instead of if-else to solve the null pointer problem
static constructor
JDK provides three static methods to construct an `Optional`
-
public
final
class
Optional<T> {
-
-
private
static
final Optional<?> EMPTY =
new
Optional<>();
-
private
final T value;
-
-
// This method is used to construct an empty Optional. If the value in the Optional is null, the Optional will not contain a value.
-
public
static<T> Optional<T>
empty
() {
-
@SuppressWarnings("unchecked")
-
Optional<T> t = (Optional<T>) EMPTY;
-
return t;
-
}
-
-
//Construct an Optional through a non-null value,
-
//The returned Optional contains the value value. For this method, the parameters passed in must not be null, otherwise NullPointerException will be thrown.
-
public
static <T> Optional<T>
of
(T value) {
-
return
new
Optional<>(value);
-
}
-
-
//The difference between this method and of method is that the parameter passed in can be null. If it is null, Optional.empty() is returned.
-
public
static <T> Optional<T>
ofNullable
(T value) {
-
return value ==
null ? empty() : of(value);
-
}
-
}
Common methods
isPresent() / ifPresent()
-
// Return true if the value exists, false otherwise
-
public
boolean
isPresent
() {
-
return value !=
null;
-
}
-
-
// If the Optional instance has a value, call consumer for it, otherwise no processing will be done.
-
public
void
ifPresent
(Consumer<? super T> consumer) {
-
if (value !=
null)
-
consumer.accept(value);
-
}
test
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
User
user
=
new
User();
-
Optional<User> optional = Optional.ofNullable(user);
-
optional.ifPresent(s -> System.out.println(s));
-
}
-
}
Get()
Get the value in Optional, which is our value. Optional is equivalent to a shell.
-
public T
get
() {
-
if (value ==
null) {
-
throw
new
NoSuchElementException(
"No value present");
-
}
-
return value;
-
}
orElse() / orElseGet() / orElseThrow()
-
// If the value in Optional is not empty, return the value in Optional. If it is empty, return the other value.
-
public T
orElse
(T other) {
-
return value !=
null ? value : other;
-
}
-
-
// If there is a value in Optional, return the value, otherwise return the result of other call
-
public T
orElseGet
(Supplier<? extends T> other) {
-
return value !=
null ? value : other.get();
-
}
-
-
// If the value in Optional exists, the value is returned. If the value does not exist, the exception in the exception function Supplier is thrown.
-
public <X
extends
Throwable> T
orElseThrow
(Supplier<? extends X> exceptionSupplier)
throws X {
-
if (value !=
null) {
-
return value;
-
}
else {
-
throw exceptionSupplier.get();
-
}
-
}
test
-
String
value
=
"2";
-
String
orElse
= Optional.ofNullable(value).orElse(
"1");
-
System.out.println(orElse);
//2
-
-
String
value
=
null;
-
String
orElse
= Optional.ofNullable(value).orElse(
"1");
-
System.out.println(orElse);
//1
-
-
-------------------------------------------------------
-
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
String
value
=
null
;
-
String
orElse
= Optional.ofNullable(value).orElseGet(OptionalTest::get);
-
System.out.println(orElse);
// 123
-
-
String
value
=
"2";
-
String
orElse
=
Optional.ofNullable(value).orElseGet(OptionalTest::get);
-
System.out.println(orElse);
// 2
-
}
-
-
public
static String
get
(){
-
return
"123";
-
}
-
}
-
-
-------------------------------------------------------
-
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
String
value
=
null;
-
String
orElse
=
Optional.ofNullable(value).orElseThrow(() -> new RuntimeException ( "Value does not exist" ));
-
System.out.println(orElse);
-
}
-
}
map() / flatMap()
-
map(Function)
: If Optional is not empty, apply Function to the content in Optional and return the result. Otherwise, Optional.empty is returned directly . -
flatMap(Function)
:Samemap()
, but the provided mapping function wraps the result in an Optional object, soflatMap()
no wrapping is done at the end.
None of the above methods are applicable to numeric Optional . Generally speaking, streams filter()
will remove stream elements when Predicate returns . The Optionalfalse
will not Optional.filter()
be deleted on failure , but will be retained and converted to empty.
-
// Pass the value in Optional as a parameter to map. If the value passed in is empty, an empty Optional object is returned, which is equivalent to Optional.empty(),
-
// If it is not empty, we can return a return value that can describe the result (the value in Optional, this value can be reassigned)
-
public<U> Optional<U>
map
(Function<? super T, ? extends U> mapper) {
-
Objects.requireNonNull(mapper);
-
if (!isPresent())
-
return empty();
-
else {
-
return Optional.ofNullable(mapper.apply(value));
-
}
-
}
-
-
// If the value in Optional exists, then return a value based on Optional (such as Optional),
-
// If the value in Optional does not exist, an empty Optional object is returned, equivalent to Optional.empty(),
-
// Unlike map, map returns a value, while flatMap returns a value based on Optional
-
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));
-
}
-
}
test
-
public
class
OptionalTest {
-
public
static
void
main
(String[] args) {
-
User
user
=
null;
-
Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
-
System.out.println(optional);
//Optional.empty
-
-
User
user
=
new
User();
-
user.setUsername(
"Admin");
-
Optional<String> optional = Optional.ofNullable(user).map(OptionalTest::getMap);
-
System.out.println(optional);
// Optional[Admin]
-
-
}
-
-
public
static String
getMap
(User user){
-
return user.getUsername();
-
}
-
-
-------------------------------------------------------
-
-
User
user
=
new
User();
-
user.setUsername(
"Admin");
-
Optional<String> optional = Optional.ofNullable(user).flatMap(OptionalTest::getFlatMap);
-
System.out.println(optional);
-
}
-
public
static Optional<String>
getFlatMap
(User user){
-
return Optional.ofNullable(user).map(User::getUsername);
-
}
-
filter()
Pass the value in Optional as a parameter. If it meets the rules, an Optional object is returned, otherwise an empty Optional object (Optional.empty) is returned.
-
public Optional<T>
filter
(Predicate<? super T> predicate) {
-
Objects.requireNonNull(predicate);
-
if (!isPresent())
-
return
this;
-
else
-
return predicate.test(value) ?
this : empty();
-
}
Actual combat
ifPresent(), this is a terminal operation. If the value exists, the specified consumption method will be called.
-
// Get the value of book, if book is null, return the default value
-
String
book
= Optional.ofNullable(person).map(Person::getBook).orElse(
"default");
-
-
// If person is not null, print salary
-
Optional.ofNullable(person).ifPresent(p -> System.out.println(p.getSalary()));
-
-
// If book is null, set the default value
-
Optional.ofNullable(person)
-
.map(Person::getComputer)
-
.ifPresent(c -> c.setBrandName(
"default name"));
-
-
Optional.ofNullable(person)
-
.map(Person::getComputer)
-
.ifPresent(
this::consumerTest);
-
-
public
void
consumerTest
(Computer computer){
-
System.out.println(
"consumer test");
-
System.out.println(computer);
-
}
-
-
// Get brand, if brandName is "", throw an exception
-
// Because map can only filter out null values, and we usually need to make other judgments at work, we can use map to parse a certain attribute in the entity class, and then use filter to perform corresponding filtering.
-
String
brand
= Optional.ofNullable(person)
-
.map(Person::getComputer)
-
.map(Computer::getBrandName)
-
.filter(b -> !b.equals(
""))
-
.orElseThrow(() -> new NumberFormatException ( "Brand is empty" ));
-
System.out.println(
"brand: " + brand);