avatarClean Code Clean Life

Summary

The article discusses the difference between Optional.orElse and Optional.orElseGet in Java, emphasizing that orElse evaluates its parameter even if the Optional is not empty, while orElseGet only evaluates its parameter when the Optional is empty.

Abstract

The blog post delves into the nuances of using Optional in Java, specifically focusing on the methods orElse and orElseGet. It illustrates through code examples that orElse evaluates its argument every time it is called, which can lead to unnecessary computation or side effects if the Optional already contains a value. In contrast, orElseGet takes a Supplier and lazily evaluates the provided expression only when the Optional is empty, thus avoiding potential performance issues and unintended behavior when dealing with non-empty Optional objects. The author demonstrates this behavior with a User class and a createUser method, showing that createUser is executed with orElse even when it is not needed, whereas orElseGet correctly defers execution. The post also highlights that passing null to orElseGet results in a NullPointerException, while orElse accepts null as a valid return value.

Opinions

  • The author suggests that using Optional.orElse can lead to inefficient code because its parameter is always evaluated, regardless of whether the Optional contains a value.
  • It is implied that developers should prefer Optional.orElseGet when they want to provide a default value that requires computation, to avoid unnecessary processing.
  • The author expresses surprise at the eagerness of orElse's parameter evaluation, indicating that this behavior might not be widely understood or expected among developers.
  • The article concludes that understanding the distinction between orElse and orElseGet is crucial for writing clean and efficient Java code, especially when dealing with optional values.

Say bye to if-else — -Part2 orElse vs orElseGet

In my previous blog https://readmedium.com/a-new-way-to-check-for-null-say-goodbye-to-if-else-part-1-8179d3b8fd0a we talked about how to clean your code by using Optional` in this blog, lets dive deaper to see whats the difference between Optional.orElse and Optional.orElseGet.

The below is from Java21 Doc

public T orElse(T other)
If a value is present, returns the value, otherwise returns other.
Parameters:
other - the value to be returned, if no value is present. May be null.
Returns:
the value, if present, otherwise other

According to https://www.baeldung.com/java-optional-or-else-vs-or-else-get

parameter of orElse() is evaluated, even when having a non-empty Optional.

Before further discussing, lets consider the following code:

the result is “b”

What do you mean by evaluated here? My understood was the method will be executed.

Please be noted in the above statement, it is saying the parameter of orElse() is evaluated, but it is NOT saying it is used.

class User {
String name;
String phone;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", phone='" + phone + '\'' +
", address=" + address +
'}';
}
Address address;
}
User user = null;
user = Optional.ofNullable(user).orElse(createUser());
System.out.println(user);
private User createUser() {
System.out.println("createUser was executed.");
User user = new User();
user.setName("John");
return user;
}

In the above code user is null, thus the createUser() was executed.

But what will happen if user is NOT null

User user1 = new User();
user1.setName("John");
System.out.println(Optional.ofNullable(user1).orElse(createUser(user1)));

The out come is:

createUser was executed.
User{name='John', phone='null', address=null}

To my surprise the createUser() method was CALLED.

What will happen if in the createUser(…) method I updated the user variable?

User user1 = new User();
user1.setName("Smith");
System.out.println("Im suppose to see the Smith user");
System.out.println(Optional.ofNullable(user1));
System.out.println("With orElse(…) Im suppose to see the John user");
System.out.println(Optional.ofNullable(user1).orElse(createUser(user1)));
private User createUser(User user ) {
System.out.println("createUser(…) was executed.");
user.setName("Smith");
return user;
}

The result is:

Im suppose to see the Smith user
Optional[User{name='Smith', phone='null', address=null}]
With orElse(…) Im suppose to see the John user
createUser(…) was executed.
User{name='John', phone='null', address=null}

My conclusion up to now is the orElse methods in the Optional class will execute the method (in my case, the createUser() method) eagerly, regardless of whether the Optional contains a non-null value or not.

Lets see the behavior of orElseGet with the same code:

User user2 = null;
user2 = Optional.ofNullable(user2).orElseGet(this::createUser);
System.out.println(user2);
System.out.println("now the user has been set");
User user3 = new User();
user3.setName("Smith");
System.out.println("Im suppose to see the Smith user");
System.out.println(Optional.ofNullable(user3).orElseGet(this::createUser));

The result is:

createUser was executed.
User{name='John', phone='null', address=null}
now the user has been set
Im suppose to see the Smith user
User{name='Smith', phone='null', address=null}

The difference between orElse and orElseGet was in orElseGet the createUser(…) method was NOT called because the variable user3 is NOT null.

Last challenge. What will happen if the default value of orElse/orElseGet was set to null? shown below:

User user4 = null;
System.out.println(Optional.ofNullable(user4).orElse(null));
System.out.println("Im using orElseGet");
System.out.println(Optional.ofNullable(user4).orElseGet(null));

orElseGet will raise NPE

🔸Thank you for reading 👍.

If you liked this story then click on 👏👏 do follow for more interesting and helpful stories.

Java17
Java Tips
Java Tutorial
Core Java Training
Java Interview
Recommended from ReadMedium