I had a coding problem to fail when a Java 8 stream was empty. One way is illustrated below in example1
. Another approach was interesting, shown in example2
public final class Streamy { private static <T, E extends RuntimeException> void example1( final Stream<T> items, final Consumer<? super T> process, final Supplier<E> thrown) throws E { if (0 == items. peek(process). count()) throw thrown.get(); } private static <T, E extends RuntimeException> void example2( final Stream<T> items, final Consumer<? super T> process, final Supplier<E> thrown) throws E { final AtomicBoolean foundSome = new AtomicBoolean(); try (final Stream<T> stream = items) { stream. onClose(() -> { if (!foundSome.get()) throw thrown.get(); }). peek(__ -> foundSome.set(true)). forEach(process); } } public static void main(final String... args) { example1(Stream.of(), out::println, RuntimeException::new); example2(Stream.of(), out::println, RuntimeException::new); } }
Comparing them I find:
- Using
count()
is shorter and more clear - Using
onClose()
is more expressive
I found it odd to use peek()
in example1
to execute the real purpose of the code, and was happy to discover onClose()
though disappointed to need try-with-resources for it to run.
It was unfortunate that the more expressive approach (peek()
for side effect, forEach()
for processing, onClose
for post-processing check) was also harder to understand.
No comments:
Post a Comment