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