flatMap
Brian Goetz
brian.goetz at oracle.com
Mon Dec 17 19:18:08 PST 2012
So, of the names suggested here so far for flatMap, my favorite is the
one inspired by Don -- mapMulti. It still sounds like map, is pretty
clear what it's about (multi-valued map), and it steers clear of a lot
of other pitfalls.
While the bikeshed paint is still wet, we can talk about the API.
Here's an improved proposal. This may not be perfect, but it's
definitely better than what we have now.
interface DownstreamContext<T> /* placeholder name */ {
void yield(T element);
void yield(T[] array);
void yield(Collection<T> collection);
void yield(Stream<T> stream);
// can add more
}
interface Multimapper<T,U> /* placeholder name */ {
void map(DownstreamContext<U> downstream, T element);
}
interface Stream<T> {
...
<U> Stream<U> mapMulti(Multimapper<T,U> mapper);
...
}
This handles the "generator" case that the current API is built around,
but also handles the other cases well too:
Example 1 -- collection.
foos.mapMulti((downstream, foo)
-> downstream.yield(getBars(foo)))...
Example 2 -- generator.
ints.mapMulti((d, i) -> { for (int j=0; j<i; j++)
d.yield(j);
})
Example 3 -- stream.
kids.mapMulti(
(d, k) -> d.yield(adults.stream().filter(a -> isParent(a, f))));
The downstream context argument is still annoying, but I think is
clearer than the current "sink" argument is. The alternative would be
to have N special-purpose functional interfaces and N overloads for the
non-generator cases (stream, collection) in addition to the current
generator form.
More information about the lambda-libs-spec-observers
mailing list