Use of HashMap in Stream functions: is there a better way?
Gernot Neppert
mcnepp02 at googlemail.com
Mon Nov 19 08:52:22 PST 2012
Hello,
there is something in the Stream-API that I find a little awkward:
All of Stream's methods either return other Streams, which can be seen
as views of the original Stream, or final types such as boolean or Optional.
Only "Stream.groupBy" and "Stream.reduceBy" return a java.util.Map,
which somehow doesn't quite fit into the framework.
It forces the implementer to pick a concrete Map implementation, but the
API doesn't convey which one.
Also, you cannot, in a single step, fill a TreeMap with the result.
The alternative that comes to my mind looks like this:
- Make java.util.Map a Stream.Destination:
interface Map<K,V> extends Stream.Destination<Map.Entry<K,V>> {
public void addAll(Stream<? extends Entry<K,V>> stream) default {
for(Entry<K,V> entry : stream) {
put(entry.getKey(), entry.getValue());
}
}
}
- And change Stream to:
interface Stream {
public <U> Stream<Map.Entry<U,T>> groupBy(Mapper<? extends U,? super
T> mapper);
}
With this change, "groupBy" could be used for mappings to unique keys as
well as for non-unique keys.
The only thing missing for this would be a "java.util.MultiMap" - but
isn't that long overdue anyway?
Examples:
// Unique Mapping:
Map<Integer,Article> byId = warehouse.stock().stream().groupBy(pojo ->
pojo.getId()).into(new HashMap<Integer,Article>());
// Non-Unique Mapping:
MultiMap<Integer,Artivle> byQuantity =
warehouse.stock().stream().groupBy(pojo -> pojo.getQuantity()).into(new
HashMultiMap<Integer,Article>());
More information about the lambda-dev
mailing list