Hi,

We have had multiple attempts at a BiStream for references.

Mike had quite a good one. I thought my last attempt was rather good too :-) it 
avoided boxing on critical paths, while avoiding much bifurcation of the 
Spliterator API, and supported some nice use-cases. However, it would likely 
stick out like a sore thumb when Value types and then Tuples arrive (when? 
“when they are ready!”), and then we can do much better.

Some small tweaks to Map.Entry might be handy, but i think beyond that and it’s 
likely to start pulling on a bigger set of use-cases.

Paul.


> On 15 Jan 2016, at 16:51, Tagir F. Valeev <amae...@gmail.com> wrote:
> 
> Hello!
> 
> SC> Finally, the Collectors class could do with a new method entriesToMap()
> SC> that collects a stream of Map.Entry back into a Map.
> 
> I was thinking about adding such collector into my library and checked
> StackOverflow to understand the useful scenarios. Seems that having
> entriesToMap() collector without arguments (even along with proposed
> mapValues()/mapKeys()) only would be too limited and solve only some
> subset of interesting problems.
> 
> First, you would need to add versions with
> a) custom merging policy
> b) custom Map factory (probably could be omitted as toMap() does not
> have such overload)
> c) both
> Answers which need this:
> http://stackoverflow.com/a/22132422/
> http://stackoverflow.com/a/33724926/
> http://stackoverflow.com/a/30084289/
> And many more
> 
> Second, to be consistent with the current API you may need to add
> entriesToConcurrentMap()
> 
> Third, sometimes you need to know both key and value to produce the
> new key. In this case proposed mapValues()/mapKeys() will not work:
> http://stackoverflow.com/a/34766036/
> 
> Fourth, very often entries from the stream should be grouped instead,
> so probably something like groupingEntries() should also be added
> (along with Map factory argument, downstream collector argument and
> concurrent version!) The most common scenario is the following:
> 
> groupingBy(Entry::getKey,
>      mapping(Entry::getValue, toList()))
> http://stackoverflow.com/a/25246138/
> http://stackoverflow.com/a/31488612/
> http://stackoverflow.com/a/30877403/
> And many more
> 
> To my opinion, creating such dedicated collector is even more
> important than toMap() as people understand toMap(Entry::getKey,
> Entry::getValue) much better than cascaded combination of groupingBy,
> mapping and toList. See Stuart Marks explaining:
> http://stackoverflow.com/a/28599035/
> 
> Sometimes it works without additional mapping:
> groupingBy(Map.Entry::getKey, summingLong(Map.Entry::getValue))
> http://stackoverflow.com/a/34325686/
> http://stackoverflow.com/a/31751786/
> 
> Also sometimes you need to swap key and value like here:
> groupingBy(e->e.getValue().get(0),
>        mapping(Map.Entry::getKey, toList()))
> http://stackoverflow.com/a/30652372/
> http://stackoverflow.com/a/33900949/
> So probably Entry<V, K> swap() method would also be useful!
> 
> In general it's not very evident where to draw the line between API
> simplicity and covered use cases. Hopefully my examples will help to
> take good decision.
> 
> By the way in my library MapStream is called as EntryStream. Like
> IntStream is stream of ints, the EntryStream is stream of entries.
> MapStream would be the stream of maps which is not true. Also in
> context of the Stream API map often means transformation which would
> add the confusion.
> 
> With best regards,
> Tagir Valeev.
> 

Reply via email to