Java - 是否有任何Stream收集器返回ImmutableMap?

Luk*_*ood 11 guava java-8

我发现自己想要一个Collectors.toMap返回的变体ImmutableMap,这样我就能做到:

ImmutableMap result = list.stream().collect(MyCollectors.toImmutableMap(
    tuple -> tuple._1(), tuple -> tuple._2());
Run Code Online (Sandbox Code Playgroud)

(tuple在这个特定的例子中是Scala Tuple2)

刚刚了解到这样的方法将在Guava 21中使用Java-8支持(耶!)但这听起来好一个月之后.有谁知道今天可能实现的任何现有库(等)?

ImmutableMap并非严格要求,但似乎是我要求的最佳选择:按键查找,并保留原始迭代顺序.不变性也是首选.

请注意,这FluentIterable.toMap(Function)还不够,因为我既需要键映射功能,也需要值映射功能.

Ale*_* C. 19

您不需要为此收集器编写匿名类.你可以Collector.of改用:

public static <T, K, V> Collector<T, ?, ImmutableMap<K,V>> toImmutableMap(
            Function<? super T, ? extends K> keyMapper,
            Function<? super T, ? extends V> valueMapper) {
    return Collector.of(
               ImmutableMap.Builder<K, V>::new,
               (b, e) -> b.put(keyMapper.apply(e), valueMapper.apply(e)),
               (b1, b2) -> b1.putAll(b2.build()),
               ImmutableMap.Builder::build);
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您不介意首先将结果收集到可变映射中,然后将数据复制到不可变映射中,则可以使用内置toMap收集器并结合collectingAndThen:

ImmutableMap<String, String> result = 
     list.stream()
         .collect(collectingAndThen(
             toMap(
                 tuple -> tuple._1(), 
                 tuple -> tuple._2()),
             ImmutableMap::copyOf));
Run Code Online (Sandbox Code Playgroud)

  • Guava现在为其集合类型提供收集器,例如[`ImmutableList.toImmutableMap()`](https://github.com/google/guava/blob/2909a996047e575cdac02ea1c06a93a9419271cf/guava/src/com/google/common/collect/ImmutableMap. Java的#L65-L82). (4认同)