1. Introduction
If you haven’t dealt with null Pointers, you’re not a real Java programmer.
NullPointException
null check
To solve this problem, a new class java.util.Optional has been introduced in Java SE8, which alleviates this problem.
As you may have noticed, I used relief rather than solution. The Optional class in Java SE8 solves the null pointer problem. The Optional class is used to remind you that there may be null values that need to be handled in a special way. If you use the Optional class as a null pointer without thinking about it, you’ll still run into errors.
Because Optional is introduced in Java SE8, this article will inevitably have some SYNTAX in JDK8, such as Lambda expressions, stream processing, etc., but all the basic form, there will not be too complex cases.
2. Optional
There are three ways to create an Optional.
/**
* 创建一个 Optional
*/
@Test
public void createOptionalTest(a) {
// Optional constructor 1-of cannot pass null
Optional<String> helloOption = Optional.of("hello");
// Optional constructor 2 - empty Specifies an Optional
Optional<String> emptyOptional = Optional.empty();
// Optional construction 3 - ofNullable Supports the Optional with a null value
Optional<String> nullOptional = Optional.ofNullable(null);
}
Copy the code
The “of” method in constructor 1 will issue a NullPointerException if the value passed in is null.
3. Optional
Optional is a wrapper object. To see if it has a value, use the isPresent method to check if it has a value.
/** * Check whether there is a value */
@Test
public void checkOptionalTest(a) {
Optional<String> helloOptional = Optional.of("Hello");
System.out.println(helloOptional.isPresent());
Optional<Object> emptyOptional = Optional.empty();
System.out.println(emptyOptional.isPresent());
}
Copy the code
The resulting output:
true
false
Copy the code
Starting with JDK11, the isEmpty method is provided to check if the opposite result isEmpty.
If you want to do something with a value. You can use the ifPresent method.
/** * If there is a value, output length */
@Test
public void whenIsPresent(a) {
// If there is no value, get the default value
Optional<String> helloOptional = Optional.of("Hello");
Optional<String> emptyOptional = Optional.empty();
helloOptional.ifPresent(s -> System.out.println(s.length()));
emptyOptional.ifPresent(s -> System.out.println(s.length()));
}
Copy the code
Output results:
5
Copy the code
4. Obtain the Optional value
Use the get method to get the value, but if the value does not exist, a NoSuchElementException is thrown.
/** * If there is no value, throw an exception */
@Test
public void getTest(a) {
Optional<String> stringOptional = Optional.of("hello");
System.out.println(stringOptional.get());
// If there is no value, an exception will be thrown
Optional<String> emptyOptional = Optional.empty();
System.out.println(emptyOptional.get());
}
Copy the code
The result is:
hello
java.util.NoSuchElementException: No value present
at java.util.Optional.get(Optional.java:135)
at net.codingme.feature.jdk8.Jdk8Optional.getTest(Jdk8Optional.java:91)
Copy the code
5. Optional Default value
With orElse, the orElseGet method can get a given default value without one.
/** * If there is no value, get the default value */
@Test
public void whenIsNullGetTest(a) {
// If there is no value, get the default value
Optional<String> emptyOptional = Optional.empty();
String orElse = emptyOptional.orElse("orElse default");
String orElseGet = emptyOptional.orElseGet(() -> "orElseGet default");
System.out.println(orElse);
System.out.println(orElseGet);
}
Copy the code
The results obtained are:
orElse default
orElseGet default
Copy the code
Now you might be wondering, these two methods look exactly the same, why are they provided? Let’s look at another example and you’ll see the difference.
/** * orElse and orElseGet */
@Test
public void orElseAndOrElseGetTest(a) {
// If there is no value, default value
Optional<String> emptyOptional = Optional.empty();
System.out.println("Empty Optional. OrElse");
String orElse = emptyOptional.orElse(getDefault());
System.out.println("Empty Optional. OrElseGet");
String orElseGet = emptyOptional.orElseGet(() -> getDefault());
System.out.println("Empty Optional. OrElse Result:"+orElse);
System.out.println("Empty Optional. OrElseGet Result:"+orElseGet);
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
// If there is no value, default value
Optional<String> stringOptional = Optional.of("hello");
System.out.println("There is value Optional. OrElse");
orElse = stringOptional.orElse(getDefault());
System.out.println("There is value Optional. OrElseGet");
orElseGet = stringOptional.orElseGet(() -> getDefault());
System.out.println("Optional. OrElse result:"+orElse);
System.out.println("Value Optional. OrElseGet result:"+orElseGet);
}
public String getDefault(a) {
System.out.println("Get the default value of.. run getDeafult method");
return "hello";
}
Copy the code
The resulting output:
Empty Optional. OrElse Obtain the default value.. Run getDeafult Method empty deafult. OrElseGet Get default value in.. Run getDeafult method empty Optional. OrElse Hello -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - values are Optional. OrElse get default values in.. Run getDeafult method value Optional. OrElseGet value Optional. OrElse Result: Hello Value OptionalCopy the code
In this example you can see that the method that orElseGet passes in does not run if it has a value. OrElse does.
6. Optional
Use orElseThrow to throw an exception when there is no value
/** * If there is no value, raise an exception */
@Test
public void whenIsNullThrowExceTest(a) throws Exception {
// If there is no value, throw an exception
Optional<String> emptyOptional = Optional.empty();
String value = emptyOptional.orElseThrow(() -> new Exception("Null value found"));
System.out.println(value);
}
Copy the code
The result is:
Java. Lang. Exception: found null at net. Codingme. Feature. Jdk8. Jdk8Optional. Lambda $whenIsNullThrowExceTest $7(Jdk8Optional.java:118)
at java.util.Optional.orElseThrow(Optional.java:290)
at net.codingme.feature.jdk8.Jdk8Optional.whenIsNullThrowExceTest(Jdk8Optional.java:118)
Copy the code
7. Optional function interface
The Optional comes with JDK8, and there are certain new features in JDK8, such as function interfaces. In Optional, there are three main methods passed into the function interface: filter, map, and flatMap. The implementation is actually another new feature of JDK8, so this is a simple demonstration, not an explanation. These will be covered later in other JDK8 feature articles.
@Test
public void functionTest(a) {
/ / filter to filter
Optional<Integer> optional123 = Optional.of(123);
optional123.filter(num -> num == 123).ifPresent(num -> System.out.println(num));
Optional<Integer> optional456 = Optional.of(456);
optional456.filter(num -> num == 123).ifPresent(num -> System.out.println(num));
/ / map
Optional<Integer> optional789 = Optional.of(789);
optional789.map(String::valueOf).map(String::length).ifPresent(length -> System.out.println(length));
}
Copy the code
The result is:
123
3
Copy the code
8. Optional
Suppose you have a computer, a sound card, and a USB. (Lombok’s @data annotation is used in the code below.)
/** * computer */
@Data
class Computer {
private Optional<SoundCard> soundCard;
}
/** * Sound card */
@Data
class SoundCard {
private Optional<Usb> usb;
}
/** * USB */
@Data
class Usb {
private String version;
}
Copy the code
Computers might have sound cards, and sound cards might have USB. So how do you get the USB version?
/** * The computer may have a sound card ** The sound card may have a USB port */
@Test
public void optionalTest(a) {
// No sound card, no Usb computer
Computer computerNoUsb = new Computer();
computerNoUsb.setSoundCard(Optional.empty());
// Get the USB version
Optional<Computer> computerOptional = Optional.ofNullable(computerNoUsb);
String version = computerOptional.flatMap(Computer::getSoundCard).flatMap(SoundCard::getUsb)
.map(Usb::getVersion).orElse("UNKNOWN");
System.out.println(version);
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
// Output if there is a value
SoundCard soundCard = new SoundCard();
Usb usb = new Usb();
usb.setVersion("2.0");
soundCard.setUsb(Optional.ofNullable(usb));
Optional<SoundCard> optionalSoundCard = Optional.ofNullable(soundCard);
optionalSoundCard.ifPresent(System.out::println);
// Output if there is a value
if (optionalSoundCard.isPresent()) {
System.out.println(optionalSoundCard.get());
}
// If there is no value in the output, there is no output
Optional<SoundCard> optionalSoundCardEmpty = Optional.ofNullable(null);
optionalSoundCardEmpty.ifPresent(System.out::println);
System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
/ / filter Usb2.0
optionalSoundCard.map(SoundCard::getUsb)
.filter(usb1 -> "3.0".equals(usb1.map(Usb::getVersion)
.orElse("UBKNOW")))
.ifPresent(System.out::println);
}
Copy the code
The result is:
UNKNOWN
-----------------
SoundCard(usb=Optional[Usb(version=2.0)])
SoundCard(usb=Optional[Usb(version=2.0)]) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --Copy the code
9. Optional
In this article, we’ve seen how to use the java.util.Optional class for Java SE8. The goal of the Optional class is not to replace every empty reference in the code, but to help design better programs so that consumers can know if there are empty values just by looking at the property type. In addition, Optional does not provide a direct way to retrieve values, forcing you to deal with non-existent cases. Indirectly insulates your program from null Pointers.
The code has been uploaded to Github.
After < >
Personal website: www.codingme.net if you like this article, you can follow the public number, grow together. Attention to the public number reply resources can not routine access to the most popular Java core knowledge collating & interview materials.