将Map.Entry列表转换为LinkedHashMap

4
我有一个列表,需要将其转换为映射(Map),但需要保持键的顺序不变,因此需要转换成LinkedHashMap。我需要像下面这样的东西:
list.stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

但是有具体类型的地图,例如:

list.stream().collect(Collectors.toCollection(LinkedHashMap::new))

可以将以上两种变体结合起来吗?
2个回答

16

是的,只需使用包含合并函数和映射供应商的Collectors.toMap变体:

<T, K, U, M extends Map<K, U>> Collector<T, ?, M> java.util.stream.Collectors.toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)

使用一个简单的合并函数(选择第一个值)将如下所示:
LinkedHashMap<KeyType,ValueType> map =
    list.stream().collect(Collectors.toMap(Map.Entry::getKey, 
                                           Map.Entry::getValue,
                                           (v1,v2)->v1,
                                           LinkedHashMap::new));

5
不要使用(v1,v2)->v1,而是使用(v1,v2) -> { throw new AssertionError("keys should already be unique"); },这样更好,可以确保键已经唯一。 - Holger

0

Streams的collect方法具有一个签名,允许您传递一个集合供应商、一个累加器和一个合并器。

    <R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);

在这种情况下,您可以使用这个。
Map existing; // keys match list values.
list.stream.collect(
    Maps::newLinkedHashMap,
    (map, item) -> map.put(item, existing.get(item),
    (l, r) -> { throw new IllegalStateException("combiner not needed here");}
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接