8

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?

2
  • @manfromnowhere it is want to 'orElse' part. Commented Jan 3, 2019 at 3:40
  • 3
    It is best practice to use orElse Commented Jan 3, 2019 at 3:40

4 Answers 4

9

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);
Sign up to request clarification or add additional context in comments.

6 Comments

container can be null as per OP's original code. You might want to change this to detail = container != null ? container.stream().findFirst().orElse(<someDefaultValue>) : <someDefaultValue>; or do a regular null check
as i understand 'container!=null || !container.isEmpty()' this condition , is check above code ?
@nullpointer i decide it write like this ' A<DD,DI> basePrescription = container != null ? container.stream().findFirst().map(DD::getPrescription).orElse(null) : null; ' are there any way to further simplify this ?
@uma not much i could think of currently with Java-8 and those possibilities of null. Edited to include a cleaner java-9 solution as well though.
@uma If its empty the branch to follow would be container.stream()... no elements hence findFirst returns Optional.empty and hence orElse(null) comes into picture.. in short it would return null.
|
5

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;

1 Comment

They are non-functional. container.isEmpty() will throw. But I assumed OP knows how to do null checks.
4

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.

Comments

1
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.