java - 从 Java 8 流创建 Guava Multimap 的最简洁方法

标签 java java-stream guava

我有一个List<Foo>想要一个Multimap<String, Foo>我们将 Foo 分组到其中是他们的getId()功能。

我正在使用 Java 8,它几乎非常棒,您可以执行以下操作:

List<Foo> foos = ...
Map<String, List<Foo>> foosById = foos.stream().collect(groupingBy(Foo::getId));

但是,我有大量代码需要 MultiMap<String, Foo>所以这并没有为我节省任何东西,我又回到使用 for 循环来创建我的 Multimap 。我是否缺少一种很好的“功能”方式?

最佳答案

您可以只使用 Guava Multimaps 工厂:

ImmutableMultimap<String, Foo> foosById = Multimaps.index(foos, Foo::getId);

或将调用转至 Multimaps.index Collector<T, A, R>接口(interface)(如下所示,在未优化的简单实现中)。

Multimap<String, Foo> collect = foos.stream()
        .collect(MultimapCollector.toMultimap(Foo::getId));

Collector :

public class MultimapCollector<T, K, V> implements Collector<T, Multimap<K, V>, Multimap<K, V>> {

    private final Function<T, K> keyGetter;
    private final Function<T, V> valueGetter;

    public MultimapCollector(Function<T, K> keyGetter, Function<T, V> valueGetter) {
        this.keyGetter = keyGetter;
        this.valueGetter = valueGetter;
    }

    public static <T, K, V> MultimapCollector<T, K, V> toMultimap(Function<T, K> keyGetter, Function<T, V> valueGetter) {
        return new MultimapCollector<>(keyGetter, valueGetter);
    }

    public static <T, K, V> MultimapCollector<T, K, T> toMultimap(Function<T, K> keyGetter) {
        return new MultimapCollector<>(keyGetter, v -> v);
    }

    @Override
    public Supplier<Multimap<K, V>> supplier() {
        return ArrayListMultimap::create;
    }

    @Override
    public BiConsumer<Multimap<K, V>, T> accumulator() {
        return (map, element) -> map.put(keyGetter.apply(element), valueGetter.apply(element));
    }

    @Override
    public BinaryOperator<Multimap<K, V>> combiner() {
        return (map1, map2) -> {
            map1.putAll(map2);
            return map1;
        };
    }

    @Override
    public Function<Multimap<K, V>, Multimap<K, V>> finisher() {
        return map -> map;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return ImmutableSet.of(Characteristics.IDENTITY_FINISH);
    }
}

关于java - 从 Java 8 流创建 Guava Multimap 的最简洁方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23003542/

相关文章:

java - 有状态 Rsocket 应用程序

java-8 - Java8 中 flatMap() 的用法

java - 如何 JUnit 测试两个 List<E> 是否以相同的顺序包含相同的元素?

java - 使用 GSON 创建 JSON 字符串

java - 如何在 spring boot rest 应用程序中使用 Swagger ui 配置带有密码流的 oAuth2

java - 在java中使用循环将递归方法转换为非递归方法

java - 使用 Java 8 Stream 将数据写入 .CSV 文件

Java 8 流获取无法调用原始类型 void 上的映射

java - Google Guava Predicates.or() 或 Predicates.and() 类型

java - 使用 Guava 的字符串列表的字典顺序