How to Check If a Java 8 Stream Is Empty

How to check if a Java 8 Stream is empty?

If you can live with limited parallel capablilities, the following solution will work:

private static <T> Stream<T> nonEmptyStream(
Stream<T> stream, Supplier<RuntimeException> e) {

Spliterator<T> it=stream.spliterator();
return StreamSupport.stream(new Spliterator<T>() {
boolean seen;
public boolean tryAdvance(Consumer<? super T> action) {
boolean r=it.tryAdvance(action);
if(!seen && !r) throw e.get();
seen=true;
return r;
}
public Spliterator<T> trySplit() { return null; }
public long estimateSize() { return it.estimateSize(); }
public int characteristics() { return it.characteristics(); }
}, false);
}

Here is some example code using it:

List<String> l=Arrays.asList("hello", "world");
nonEmptyStream(l.stream(), ()->new RuntimeException("No strings available"))
.forEach(System.out::println);
nonEmptyStream(l.stream().filter(s->s.startsWith("x")),
()->new RuntimeException("No strings available"))
.forEach(System.out::println);

The problem with (efficient) parallel execution is that supporting splitting of the Spliterator requires a thread-safe way to notice whether either of the fragments has seen any value in a thread-safe manner. Then the last of the fragments executing tryAdvance has to realize that it is the last one (and it also couldn’t advance) to throw the appropriate exception. So I didn’t add support for splitting here.

Java - Check Not Null/Empty else assign default value

If using JDK 9 +, use Objects.requireNonNullElse(T obj, T defaultObj)

Do we need to check if a Stream in java 8 if it is null and not iterate

No, it's not necessary¹.

As long as you use empty Streams instead of null (for example as method parameters), everything works just fine. You don't need to check if a Stream is empty, just like you don't need to check if a Collection is empty, if you use empty collections instead of nulls in your code (and you should).

¹ Now this is assuming "original" streams coming from a continuous source (collection, generator). You can easily create a null-containing Stream with something like map(o -> o.getPossiblyNull()). In this case you may want to use .filter(Objects::nonNull) to remove any null elements from the Stream.

Java Lambda - check if an ArrayList to Stream is empty

Stream.findFirst returns an Optional, its up to you to check if the optional has a value rather than just calling get.

You could use the orElse method to return a default value if the optional is empty.

Checking if a list is empty in java 8

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.

if stream().filter is empty

I would suggest creating a constructor for Foo accepting name.

You can then extract the name with default value of Optional:

Foo foo = dep.getFoo()
.stream()
.filter(f -> f.getName().equals(doo.getName))
.findAny().orElse(new Foo("Exp"));
user.setFoo(foo);

As Holger cleverly noticed using orElseGet would avoid executing the Supplier in case the Optional is not empty (beneficial if the computation is complex or side effects occur):

Foo foo = dep.getFoo()
.stream()
.filter(f -> f.getName().equals(doo.getName))
.findAny().orElseGet(() -> new Foo("Exp"));
user.setFoo(foo);

Since java 11 you can use ifPresentOrElse:

dep.getFoo()
.stream()
.filter(f -> f.getName().equals(doo.getName))
.findAny()
.ifPresentOrElse(user::setFoo, () -> user.setFoo(new Foo("Exp")));

P.S.: If you cannot create the constructor, you can just create the method to provide it and use it in the above snippet:

public static Foo defaultFoo() {
Foo foo = new Foo();
foo.setName("Exp");
return foo;
}

Java 8 stream operation on empty list

collect is a terminal operation, so it must be evaluated.

When terminating a Stream pipeline with collect(Collectors.toList()), you'll always get an output List (you'll never get null). If the Stream is empty (and it doesn't matter if it's empty due to the source of the stream being empty, or due to all the elements of the stream being filtered out prior to the terminal operation), the output List will be empty too.

Null safe Collection as Stream in Java 8

You can use org.apache.commons.collections4.CollectionUtils::emptyIfNull function:

import static org.apache.commons.collections4.CollectionUtils.emptyIfNull;

emptyIfNull(list).stream()
.filter(...);

Java 8 throw exception if stream returns no results

You could try this:

Collection<Foo> foo = blah.stream().filter(somePredicate)
.collect(Collectors.collectingAndThen(Collectors.toList(), Optional::of))
.filter(l -> !l.isEmpty())
.orElseThrow(() -> new Exception("blah"))

Note that comparing to your code this allocates an extra Optional instance.



Related Topics



Leave a reply



Submit