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.