从java8流创建番石榴MultiMap的最简洁方法 [英] Cleanest way to create a guava MultiMap from a java8 stream

查看:1327
本文介绍了从java8流创建番石榴MultiMap的最简洁方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列表< Foo> ,想要一个 Multimap< String,Foo> 我们在哪里分组 Foo getId()函数。

I have a List<Foo> and want a Multimap<String, Foo> where we've grouped the Foo's by their getId() function.

我正在使用Java 8,它的功能非常棒:

I am using Java 8 and its almost awesome in that you can do:

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

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

However, I have a good amount of code that wants a MultiMap<String, Foo> so this doesnt save me anything and I'm back to using a for-loop to create my MultiMap. Is there a nice "functional" way that I am missing?

推荐答案

你可以使用Guava Multimaps工厂:

You can just use the Guava Multimaps factory:

Multimaps.index(foos, Foo::getId);

或用Collector接口封装对Multimaps.index的调用(如下所示,在未优化的天真实现中) )。

or wrap a call to Multimaps.index with a Collector interface (shown below, in an unoptimized naive implementation).

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

和收藏家:

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);
    }
}

这篇关于从java8流创建番石榴MultiMap的最简洁方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆