首页 > 解决方案 > Absence of toMap method with key, value and map supplier in Collectors

问题描述

Collectors.toMap has three overloaded variants.

1. Key and value mapper:

toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)

2. Extending 1 adding a merge function:

toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)

3. Extending 2 with a map supplier:

toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)

I wonder why there isn't a method taking a key supplier, value supplier and a map supplier.

This would be useful in cases when I want to use a different map(other than a HashMap) and I know for sure that my key mapping function would not generate duplicate keys.

To achieve this, I either have to pass (a simple) lambda for the mergeFunction

persons.stream()
        .collect(Collectors.toMap(Person::getId, Function.identity(),
                (a, b) -> a, 
                LinkedHashMap::new));

or, use Collectors.collectingAndThen

persons.stream()
        .collect(Collectors.collectingAndThen(Collectors.toMap(Person::getId, Function.identity()),
                LinkedHashMap::new));

EDIT:

As pointed out by @Holger in the comments, copying into a LinkedHashMap won't help as the order has already been changed when populating the map by the toMap method

[..]collectingAndThen does not achieve the goal, as copying the unordered map into a LinkedHashMap after the fact does not restore the order

标签: javajava-8

解决方案


推荐阅读