How to convert following method to java 8?

Viewed 352

I have List object and I need to take the first element on the list if it is not null or empty.

I write below code using java and now I want to convert it to Java 8.

    List<DD> container
    A<DD,DI> a;
    if(container!=null || !container.isEmpty()){
       for(DD dd:container)
       {
          a = dd.getPrescription();
          break;
       }
    }

I convert it like this.

 DD detail = container.stream().findFirst().get();

I need to know this is correct?

4 Answers

There is a critical flaw in your current code, i.e.

if(container!=null || !container.isEmpty())

this can still throw a NullPointerException (when container == null), unless the conditional operator is changed to &&. Post which the implementation below would be what I would suggest following.


It's almost correct, in the sense that you need to handle some default value if the conditions are not met :

DD detail = container.stream().findFirst().orElse(null); // or some default value instead of 'null'

If the container itself could be null, use

DD detail = container != null ? 
                container.stream().findFirst().orElse(null) : null;

In the case when you need the prescription from this object, use map as :

container.stream().findFirst().map(DD::getPrescription).orElse(null)
//                               ^^
//                               return type of prescription then

With Java-9, this could have been much simpler as :

A<DD, DI> basePrescription = Stream.ofNullable(container) // Java-9 API
                                   .flatMap(List::stream)
                                   .findFirst()
                                   .map(DD::getPrescription)
                                   .orElse(null);

This is way easier:

A<DD,DI> a = container.get(0).getPrescription();

While this is a direct translation of your original code, you probably intended something like that:

A<DD,DI> a = container != null && !container.isEmpty()
    ? container.get(0).getPrescription()
    : null;

As of JDK9, there is a new method T requireNonNullElse(T obj, T defaultObj) which essentially returns the first argument if it is non-null and otherwise returns the non-null second argument.

We can, therefore, simplify your code to:

Objects.requireNonNullElse(container, Collections.emptyList())
       .stream()
       .findFirst()
       .map(DD::getPrescription);

This returns an Optional<T> where T is whatever type getPrescription is. depending on the context and whether it's appropriate you might want to use .orElse(null); to get the value the optional contains or else a null value but there are also several other methods in the Optional<T> API which you might find more useful when extracting the value from the optional.

The findFirst() method finds the first element in a Stream. This method is used when you specifically want the first element from a sequence.

a) container.stream().findFirst().orElse(null);
b) container.stream().filter(Objects::nonNull).findFirst().orElse(null);
c)container.stream().filter(StringUtils::isNotBlank).findFirst();
or as lambdas:
d)container.stream().filter(s -> StringUtils.isNotBlank(s)).findFirst();

e)container.stream().filter(StringUtils::isNotBlank).findFirst()

For reference:- http://www.geekabyte.io/2015/01/using-optional-effectively-in-java-8.html

Related