Other answers and comments are true in that to check the contents of a stream, you must add a terminal operation, thereby โconsumingโ the stream. However, you can do this and return the result back to the stream without buffering the entire contents of the stream. Here are some examples:
static <T> Stream<T> throwIfEmpty(Stream<T> stream) { Iterator<T> iterator = stream.iterator(); if (iterator.hasNext()) { return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false); } else { throw new NoSuchElementException("empty stream"); } } static <T> Stream<T> defaultIfEmpty(Stream<T> stream, Supplier<T> supplier) { Iterator<T> iterator = stream.iterator(); if (iterator.hasNext()) { return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false); } else { return Stream.of(supplier.get()); } }
Basically translate the stream into Iterator to call hasNext() on it, and if true, return Iterator back to Stream . This is inefficient, since all subsequent operations on the stream will go through the Iterator hasNext() and next() methods, which also implies that the stream is efficiently processed sequentially (even if it later became parallel). However, this allows you to test a stream without buffering all of its elements.
There is probably a way to do this using Spliterator instead of Iterator . This potentially allows the returned stream to have the same characteristics as the input stream, including parallel operation.
Stuart Marks Oct 30 '14 at 17:20 2014-10-30 17:20
source share