Thanks Viktor, The flexibility of streams and gatherers is always impressive. Thanks for the example.
The example makes sense, I actually did something quite similar myself, except using plain mapMulti from the base stream api itself. It is a shame that the core functionality is not quite there, but the workarounds are good enough for my purposes, for now. Ty for the help! On Tue, Jun 2, 2026 at 7:23 AM Viktor Klang <[email protected]> wrote: > Hi David, > > This is a really complex topic, and there are interactions between > things like Errors/RuntimeExceptions and Throwables, together with > sequential evaluation, parallel evaluation, partial evaluation etc. > > That being said, Gatherers are extremely versatile, and you could > experiment with encodings that would allow you to add the kind of > information you need. > > The following is just an example I threw together to illustrate what I > mean: > > jshell> public static <T, R> Gatherer<T, ?, R> wrap(Function<? super T, > ? extends Stream<? extends R>> f, BiFunction<? super T, ? super > RuntimeException, ? extends RuntimeException> wrapper) { > ...> return Gatherer.<T, Void, R>of( // flatMap-semantics > ...> Gatherer.defaultInitializer(), > ...> (_, element, downstream) -> { > ...> try(Stream<? extends R> s = f.apply(element)) { > ...> return s != null ? > s.sequential().allMatch(downstream::push) : true; // Not ideal > performance-wise, yet semantically works > ...> } catch (RuntimeException re) { > ...> throw wrapper.apply(element, re); > ...> } > ...> }, > ...> (Void x, Void y) -> x, // "custom" combiner so this > operation can be parallelized > ...> Gatherer.defaultFinisher() > ...> ); > ...> } > | created method wrap(Function<? super T, ? extends Stream<? extends > R>>, BiFunction<? super T, ? super RuntimeException, ? extends > RuntimeException>) > > jshell> Stream.of(1,2, 0, 3).gather(wrap(i -> Stream.of(i).map(x -> 10 / > x), (i, e) -> new IllegalStateException("Error when processing: " + i, > e))).toList(); > | Exception java.lang.IllegalStateException: Error when processing: 0 > | ... // trace here > | Caused by: java.lang.ArithmeticException: / by zero > | ... // trace here > > > On 2026-06-02 02:17, David Alayachew wrote: > > Whoops, let me improve that method signature. > > > > public <X1 extends Throwable, X2 extends Throwable> Stream<T> > > wrapException(Class<X1> excClass, Function<X1, X2> excTransformer) > > -- > Cheers, > √ > > > Viktor Klang > Software Architect, Java Platform Group > Oracle > >
