Optional air judgment operation manual

We programmers do a lot of null value checking. Although sometimes this kind of inspection is completely unnecessary, we are used to routine. Finally, Java 8 couldn't stand it anymore, so we introduced Optional so that the code we wrote was no longer so mean and inflexible.
Pull the name of a member from the database according to the member ID, and then print the name to the console:

@SpringBootTest
public class SpringbootTest {
    @Test
    void contextLoads() {
        Member mem = getMemberByIdFromDB();
        if (mem != null) {
            System.out.println(mem.getName());
        }
    }
    public static Member getMemberByIdFromDB() {
        // Member with current ID does not exist
        return null;
    }
}
class Member {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

Since the member with the current ID does not exist, the getMemberByIdFromDB() method returns null as the result of not obtaining the member, which means that mem must be null first when printing the member name, otherwise NPE exception will be thrown:

1 how does optional solve this problem

@SpringBootTest
public class SpringbootTest {
    @Test
    void contextLoads() {
        Optional<Member> optional = getMemberByIdFromDB();
        optional.ifPresent(mem -> {
            System.out.println("The member's name is:" + mem.getName());
        });
    }
    public static Optional<Member> getMemberByIdFromDB() {
        boolean hasName = true;
        if (hasName) {
            return Optional.of(new Member("Silent King II"));
        }
        return Optional.empty();
    }
}
class Member {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Member(String name) {
        this.name = name;
    }
}

The getMemberByIdFromDB() method returns Optional < Member > as the result, which indicates that the Member may or may not exist. At this time, you can use Lambda expression in the ifPresent() method of Optional to directly print the result. The reason why Optional can solve the problem of NPE is that it clearly tells us that it does not need to be judged empty.

2 create an Optional object

1) You can create an empty Optional object using the static method empty():

Optional<String> empty = Optional.empty();
System.out.println(empty); // Output: optional empty

2) You can use the static method of() to create a non empty Optional object:

Optional<String> opt = Optional.of("Silent King II");
System.out.println(opt); // Output: Optional

Of course, the parameter passed to the of() method must be non empty, that is, it cannot be null, otherwise NullPointerException will still be thrown.

String name = null;
Optional<String> optnull = Optional.of(name);


3) You can use the static method ofNullable() to create an Optional object that can be empty or non empty:

String name = null;
Optional<String> optOrNull = Optional.ofNullable(name);
System.out.println(optOrNull); // Output: optional empty

There is a ternary expression inside ofNullable() method. If the parameter is null, the private constant EMPTY is returned; Otherwise, a new Optional object is created using the new keyword -- no more NPE exceptions will be thrown.

3. Judge whether the value exists

You can judge whether an Optional object exists through the isPresent() method. If it exists, the method returns true, otherwise it returns false -- replacing obj= Null judgment.

Optional<String> opt = Optional.of("Silent King II");
System.out.println(opt.isPresent()); // Output: true
Optional<String> optOrNull = Optional.ofNullable(null);
System.out.println(optOrNull.isPresent()); // Output: false

4 non empty expression

The Optional class has a very modern method, ifPresent(), which allows us to execute some code in a functional programming way, so I call it a non empty expression. If there is no such method, we usually need to empty the Optional object through isPresent() method before executing the corresponding code:

Optional<String> optOrNull = Optional.ofNullable(null);
if (optOrNull.isPresent()) {
    System.out.println(optOrNull.get().length());
}

With ifPresent(), the situation is completely different. You can directly pass the Lambda expression to the method, and the code is more concise and intuitive.

Optional<String> opt = Optional.of("Silent King II");
opt.ifPresent(str -> System.out.println(str.length()));

5 set (get) default value

Sometimes, when we create (get) an Optional object, we need a default value, and the orElse() and orElseGet() methods come in handy.
The orElse() method is used to return the value wrapped in the Optional object. If the value is not null, it will return; Otherwise, the default value is returned. The parameter type of this method is consistent with the value type.

String nullName = null;
String name = Optional.ofNullable(nullName).orElse("Silent King II");
System.out.println(name); // Output: silent King II

The orElseGet() method is similar to the orElse() method, but the parameter types are different. If the value in the Optional object is null, the function in the parameter is executed.

String nullName = null;
String name = Optional.ofNullable(nullName).orElseGet(()->"Silent King II");
System.out.println(name); // Output: silent King II

Judging from the output results and the form of code, the two methods are very similar, which inevitably raises our doubts. Is it necessary for the designer of Java class library to do so?
Suppose there is a traditional way to get the default value:

@SpringBootTest
public class SpringbootTest {
    @Test
    void contextLoads() {
        String name = null;
        System.out.println("orElse");
        String name2 = Optional.ofNullable(name).orElse(getDefaultValue());

        System.out.println("orElseGet");
        String name3 = Optional.ofNullable(name).orElseGet(SpringbootTest::getDefaultValue);

    }
    public static String getDefaultValue() {
        System.out.println("getDefaultValue");
        return "Silent King II";
    }

}

Note: Class Name:: method name is the syntax introduced by Java 8, and there is no () after the method name, indicating that the method may not be called.
The output results are as follows:

orElse
getDefaultValue

orElseGet
getDefaultValue

The output results are similar without much difference, which is when the value of the Optional object is null. What if the value of the Optional object is not null?

String name = "Silent King three";
System.out.println("orElse");
String name2 = Optional.ofNullable(name).orElse(getDefaultValue());

System.out.println("orElseGet");
String name3 = Optional.ofNullable(name).orElseGet(SpringbootTest::getDefaultValue);

The output results are as follows:

orElse
getDefaultValue
orElseGet

orElseGet() did not call getDefaultValue(). Which method performs better, do you understand?

6 get value

Intuitively and semantically, the get() method is the most authentic method to obtain the value of the Optional object, but unfortunately, this method is flawed, because if the value of the Optional object is null, this method will throw a NoSuchElementException exception. This is completely contrary to our original intention of using the Optional class.

String name = null;
Optional<String> optOrNull = Optional.ofNullable(name);
System.out.println(optOrNull.get());


It is recommended that the orElseGet() method get the value of the Optional object.

7 filter value

The length of the password is checked when the user registers. The filter() method of the Optional class comes in handy.

String password = "12345";
Optional<String> opt = Optional.ofNullable(password);
System.out.println(opt.filter(pwd -> pwd.length() > 6).isPresent());

Continue with various operations in combination with stream

Special thanks: silent King II

Keywords: Java Back-end Middleware

Added by akshay on Sat, 05 Mar 2022 14:56:12 +0200