Explain Codes LogoExplain Codes Logo

How to check if a Java 8 Stream is empty?

java
performance
best-practices
collections
Nikita BarsukovbyNikita Barsukov·Feb 15, 2025
TLDR

To swiftly determine whether a Stream is empty in Java, you could make use of findFirst() in conjunction with the Optional.isEmpty() method:

boolean isEmpty = stream.findFirst().isEmpty();

The isEmpty() method was provided by Optional starting from Java 11, aiding towards improved intuitiveness and straightforwardness. For those specifically working with Java 8 who do not have access to isEmpty(), you can perform the same action as follows:

boolean isEmpty = !stream.findAny().isPresent();

This method is beneficial as it effectively checks for emptiness in the stream without the requirement of full stream materialization.

Efficient empty check practices

When engaging with streams, optimizing for performance is a key factor, especially if there are large datasets involved. Here are some methods to verify a stream's emptiness while conserving system resources:

The findAny() and isPresent() ensemble

boolean isEmpty = !stream.findAny().isPresent();

This one-liner directly checks stream and won't consume the beast if it's only hungry for one element.

Custom Spliterator approach

Spliterator<T> spliterator = stream.spliterator(); boolean isEmpty = !spliterator.tryAdvance(e -> {});

This strategy constructs a custom Spliterator that can peek into the stream for checking emptiness during non-terminal operations without consuming the elements. This is Spliterator's got talent!

Working with Exceptions

stream.findAny().ifPresent(s -> { throw new RuntimeException("Stream is not empty!"); });

This pattern is convenient when your stream should be empty. The above statement acts as a sentry, raising an alarm (or rather, an exception) when the stream is not empty, much like getting an unexpected guest at your party.

Converting an Iterator to a Stream

Iterator<T> iterator = stream.iterator(); Stream<T> streamFromIterator = StreamSupport.stream(spliterator, stream.isParallel()); boolean isEmpty = !iterator.hasNext();

The last line checks for emptiness without consuming elements, thus ensuring that the original Stream remains unaltered like a forest under a conservation order.

Advanced empty check patterns

Here, you'll learn about alternative methods with illustrative examples and a sprinkle of humor.

The map and orElse duo

boolean isEmpty = stream.map(e -> true).findAny().orElse(false);

It's like playing bingo. If there's no prize (element), orElse comes to the rescue, declaring it a dud (in this case, false).

Dealing with parallel streams

boolean isEmpty = stream.parallel().noneMatch(x -> true);

It's like asking every thread in parallel - "Anyone got stuff? No? Great, it's empty!" -noneMatch is your buddy in the world of parallel streams.

Exception Handling for non-terminal operations

stream.peek(e -> throw new IllegalStateException("Stream is not empty!")).collect(Collectors.toList());

If a bear tries to peek at your picnic basket (non-terminal operation), this throws an exception and foils its plans.