Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a list is empty in java 8

I am new to Java8. I have implemented lists and filters. I have done a null check in my code. I would appreciate some help with how to check if the list is not empty in the same code snippet. If the list is not empty then the code should proceed with the assertion.

    list.stream().filter(listElement -> listElement != null).
    forEach((listElement) -> Assert.assertEquals(
        ValueType.CANDY,
        listElement.getCandyType()));
like image 583
Drools_user Avatar asked Dec 22 '15 23:12

Drools_user


2 Answers

You are asking an obsolete question. Streams process all elements of a source, hence, if there are no elements, no action will be taken. Therefore, you don’t need to check whether the list is empty.

Still, you can simplify your code:

list.stream().filter(Objects::nonNull)
    .map(listElement -> listElement.getCandyType())
    .forEach(candyType -> Assert.assertEquals(ValueType.CANDY, candyType));

or

Assert.assertTrue(list.stream().filter(Objects::nonNull)
                      .map(listElement -> listElement.getCandyType())
                      .allMatch(Predicate.isEqual(ValueType.CANDY));

allMatch follows the rules required for this check. If there are no elements, there is no contradicting element, hence all match. Note that listElement -> listElement.getCandyType() also can be replaced by a method reference of the form ClassName::getCandyType; I didn’t do it here as I don’t know the correct class name.

There is no performance difference between both variants. allMatch will return immediately when encountering the first non-matching element, and assertEquals will throw on the first non matching element. In the second case, the stack trace won’t show artifacts of the stream API implementation.

The second one is preferred when you provide checks for production code rather than unit tests and allow to turn these checks off, as with the Java Language assert feature, e.g.

assert list.stream().filter(Objects::nonNull)
           .map(listElement -> listElement.getCandyType())
           .allMatch(Predicate.isEqual(ValueType.CANDY));

as this form guarantees that there will be no overhead when assertions are turned off, whereas the first variant, having an assert statement with the forEach action may still cause iterating over all elements and performing the intermediate steps of the pipeline.

like image 194
Holger Avatar answered Sep 19 '22 07:09

Holger


The chosen answer is great, just a small suggestion to handle null case with Optional.ofNullable of the newly introduced to Java8 Optional class:

  Optional.ofNullable(list)
            .orElseGet(Collections::emptyList)
            .stream().filter(Objects::nonNull)
            .map(listElement -> listElement.getCandyType())
            .forEach(candyType -> Assert.assertEquals(ValueType.CANDY, candyType)););
like image 41
Johnny Avatar answered Sep 23 '22 07:09

Johnny