Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional.ofNullable and method chaining

I was surprised by Optional.ofNullable method. Some day I wrote a function that supposed to return an Optional:

private Optional<Integer> extractFirstValueFrom(InsightsResponse insight) {     return Optional.ofNullable(insight.getValues().get(0).getValue()); } 

I mistakenly thought that Optional.ofNullable will prevent any NullPointerExceptions inside of argument expression.

Now I think I know that it was very foolish idea. Java have to resolve arguments first to pass it to Optional.ofNullable invocation.

But I have a question. Is there a nice and good way to accomplish my goal? I would like to obtain from expression insight.getValues().get(0).getValue() some Integer value or null. Null can be each one of the expressions: insight.getValues() or insight.getValues().get(0).

I know that I can just put this in try/catch block but I am wondering if there is more elegant solution.

like image 249
sebast26 Avatar asked Feb 11 '16 10:02

sebast26


People also ask

What is optional ofNullable?

What is the ofNullable() method of the Optional class? The ofNullable() method is used to get an instance of the Optional class with a specified value. If the value is null , then an empty Optional object is returned.

What is optional Chaining in Java?

The purpose of chaining Optionals in a Stream is to pick the first Optional which has a value and return it. You could have multiple service methods which return Optionals. Passing them to a Stream as method references allows you to process them lazily and return as soon as there's something to return.

Why we use optional instead of null check?

In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present.

What are optional methods?

Optional is a container object used to contain not-null objects. Optional object is used to represent null with absent value. This class has various utility methods to facilitate code to handle values as 'available' or 'not available' instead of checking null values.


2 Answers

If you have no idea what can be null, or want to check everything for null, the only way is to chain calls to Optional.map:

If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.

As such, if the mapper return null, an empty Optional will be returned, which allows to chain calls.

Optional.ofNullable(insight)         .map(i -> i.getValues())         .map(values -> values.get(0))         .map(v -> v.getValue())         .orElse(0); 

The final call to orElse(0) allows to return the default value 0 if any mapper returned null.

like image 86
Tunaki Avatar answered Sep 21 '22 11:09

Tunaki


smth like this should work

Optional.ofNullable(insight.getValues()).map(vals -> vals.get(0)).map(v -> v.getValue()) 

well, according to the sample code given, as #extractFirstValueFrom do not contain neither @Nullable nor checks for null like Guava's checkNotNull(), let's assume that insight is always something. thus wrapping Optional.ofNullable(insight.getValues()) into Option would not result with NPE. then call chain of transformations is composed (each results with Optional) that lead to result Optional<Integer> that might be either Some or None.

like image 25
hahn Avatar answered Sep 21 '22 11:09

hahn