Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 avoiding null pointer checks using Optional

Is it possible to write something like this and to avoid checking if elements are not null and collections not empty:

 response.getBody()
    .getRequestInformation()
    .getRequestParameters().get(0)
    .getProductInstances().get(0)
    .getResultParameters()

I found something like this http://winterbe.com/posts/2015/03/15/avoid-null-checks-in-java/

Basically, what I want to achieve is to avoid if statement with multiple checking weather object is null or collection is empty in the hierarchy. I read in the post from my above that this is possible with Optional "Null checks are automatically handled under the hood."

If there is some solution already, sorry for making duplicate and please refer me to it.

like image 719
Aleksandar Avatar asked Mar 10 '23 17:03

Aleksandar


1 Answers

If you want to chain Optional, you can use its map(Function<? super T,? extends U> mapper) method to call the mapper function only if it is not null and use flatMap(Stream::findFirst) to get the first element of your Collection as next:

Optional<List<ResultParameterClass>> parameters = Optional.ofNullable(response)
    .map(ResponseClass::getBody)
    .map(BodyClass::getRequestInformation)
    .map(RequestInformationClass::getRequestParameters)
    .map(Collection::stream)
    .flatMap(Stream::findFirst)
    .map(RequestParameterClass::getProductInstances)
    .map(Collection::stream)
    .flatMap(Stream::findFirst)
    .map(ProductInstanceClass::getResultParameters);

Is it possible to return the list if present in Optional, or if not present then return something like new ArrayList<ResultParameterClass>()?

Yes it is, you simply need to use orElseGet(Supplier<? extends T> other) or orElse(T other) to provide a default value, the result won't be an Optional anymore but a List<ResultParameterClass>.

So the code would then be:

List<ResultParameterClass> parameters = Optional.ofNullable(response)
    ...
    .map(ProductInstanceClass::getResultParameters)
    .orElseGet(ArrayList::new);
like image 90
Nicolas Filotto Avatar answered Mar 21 '23 02:03

Nicolas Filotto