簡體   English   中英

從 Java 8 流創建 Guava Multimap 的最簡潔方法

[英]Cleanest way to create a Guava Multimap from a Java 8 stream

我有一個List<Foo>並且想要一個Multimap<String, Foo> ,我們已經通過它們的getId()函數對Foo分組。

我正在使用 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);

或使用Collector<T, A, R>接口包裝對 [ Multimaps.index ] 的調用(如下所示,在未優化的幼稚實現中)。

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

Guava 21.0 引入了幾種返回Collector實例的方法,這些方法會將Stream轉換為Multimap ,該Multimap將函數應用於其元素的結果分組。 這些方法是:

ImmutableListMultimap<String, Foo> foosById = foos.stream().collect(
        ImmutableListMultimap.toImmutableListMultimap(
                Foo::getId, Function.identity()));
ImmutableSetMultimap<String, Foo> foosById = foos.stream().collect(
        ImmutableSetMultimap.toImmutableSetMultimap(
                Foo::getId, Function.identity()));
HashMultimap<String, Foo> foosById = foos.stream().collect(
        Multimaps.toMultimap(
                Foo::getId, Function.identity(), HashMultimap::create)
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM