Checking if a list is empty in java 8

Drools_user picture Drools_user · Dec 23, 2015 · Viewed 97.7k times · Source

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()));

Answer

Holger picture Holger · Dec 23, 2015

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.