Java 8 starts the new Optional class - Methods in Optional

Conditions for use of fPresent()

ifPresent() method allows us to judge whether the object we need to operate on is Null before the next operation on the object. Before there is no Optional object, we usually use the following method to judge first:

if(name != null) {
    System.out.println(name.length());
}
copy

The above program logic is to first judge whether the variable name is empty. If it is not empty, the program is allowed to continue to the next step.

This judgment method is not very beautiful, and the code is ugly. More importantly, this judgment method is also error prone.

Who can guarantee that the variable will not be used again after we check the null and print out the variable? Who can guarantee that we will not forget the null check when the variable is used again?

At the same time, it is possible to cause an empty object exception, NullPointerException, when the program is running. Especially when the program fails due to input problems and cannot be started, this is usually because the program itself is not well designed and coded.

Optional can clearly handle variables that may be empty, which is a good coding habit.

Let's see how the above code is implemented in the Java 8 environment.

In the case of common functional programming, we use functional programming after the object is not null checked:

    @Test
    public void givenOptional_whenIfPresentWorks_thenCorrect() {
        Optional<String> opt = Optional.of("HoneyMoose");
        opt.ifPresent(name -> LOG.debug("{}", name.length()));
    }
copy

In the above example, we only used 2 lines of code to implement the 5 lines of code required by the first method.

The first line of code uses the Optional object to wrap our variables, and the second line of code performs corresponding operations on the wrapped Optional object.

The orElse() method to define the default value

orElse() is used to get the internal value in the Optional instance.

This method only needs one parameter. If the value in the Optional object is not empty, the program will return the value in the Optional object. Otherwise, the value of the input parameter in the orElse method will be used to replace the output.

Of course, you can also call a method in orElse(). We will explain the difference between orElseGet() and orElseGet().

Consider the following code:

    @Test
    public void whenOrElseWorks_thenCorrect() {
        String nullName = null;
        String name = Optional.ofNullable(nullName).orElse("john");
        assertEquals("john", name);
    }
copy

orElseGet() method to define the default value

The orElseGet() and orElse() methods are similar.

As we all know, if the option is empty and the orElse() method is used, the parameters entered in this method will be used to replace the return. orElseGet() is a step closer.

orElseGet provides a functional interface. You can use function programming in orElseGet(). The returned result is the result of the operation of this function.

    @Test
    public void whenOrElseGetWorks_thenCorrect() {
        String nullName = null;
        String name = Optional.ofNullable(nullName).orElseGet(() -> "john");
        assertEquals("john", name);
    }
copy

Comparison of orElse() and orElseGet() methods

Like many programmers, if you start to contact Java 8, you may not understand the different execution between orElse() and orelseget() methods, and feel that these two methods are functionally repeated.

In fact, it seems so, but in fact, there are some subtle differences.

If you don't understand these subtle differences, it may seriously affect the execution efficiency of your program.

Simply put, it is the difference between whether the functions defined in it are executed or not. Regardless of whether the previous judgment on Optional is null, the methods called in orElse() will be executed, but orElseGet() will not.

First, let's define a getMyDefault() method in the test class. This method does not use any parameters, but just prints and returns a string:

public String getMyDefault() {
    System.out.println("Getting Default Value");
    return "Default Value";
}
copy

Then we use orElse() and orElseGet() to call this method. Let's see the difference.

When the Optional object is empty

@Test
public void whenOrElseGetAndOrElseOverlap_thenCorrect() {
    String text = null;

    String defaultText = Optional.ofNullable(text).orElseGet(this::getMyDefault);
    assertEquals("Default Value", defaultText);

    defaultText = Optional.ofNullable(text).orElse(getMyDefault());
    assertEquals("Default Value", defaultText);
}
copy

As we can see, because the Optional object is empty, all the functions we defined are called.

The output of the program is as follows. It can be seen from the output of the program that the execution of these two methods is the same.

The side effect is:

Getting default value...
Getting default value...
copy

The Optional object is NOT empty

Use the same code as above, but the difference this time is that the Optional object we defined is not empty

    @Test
    public void whenOrElseGetAndOrElseDiffer_thenCorrect() {
        String text = "Text present";
        LOG.debug("Using orElseGet:");
        String defaultText = Optional.ofNullable(text).orElseGet(this::getMyDefault);
        assertEquals("Text present", defaultText);

        LOG.debug("Using orElse:");
        defaultText = Optional.ofNullable(text).orElse(getMyDefault());
        assertEquals("Text present", defaultText);
    }
copy

As shown in the above code, the Optional object we need to judge is no longer empty. The output of the program is as follows:

Using orElseGet:
Using orElse:
Getting default value...
copy

Note that the orElseGet() method will not call getMyDefault when we check that the Optional object is not empty.

Then let's take a look at the orElse() method. Although the Optional object is not empty, the method called in the orElse() method is still executed once.

If we create an object, we will create an object that has never been used. Under the garbage collection of the JVM, the created object will then be recycled and destroyed.

Consider an extreme case. If the getMyDefault() method we defined is not as simple as creating objects and destroying them, assuming that we need to query the database or access HTTP, this will lead to great overhead of the program.

Generally, we all know that creating database connections is very resource consuming during database query.

Therefore, this is the difference between the two methods when they are used. The main difference is that the Optional object is not empty.

https://www.ossez.com/t/java-8-optional-optional/13967

Posted by Renich on Tue, 17 May 2022 18:10:20 +0300