[英]Is there a way to get a tailMap or a headMap from an immutable Guava sorted 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.toImmutableListMultimap
— 創建一個ImmutableListMultimap
ImmutableSetMultimap.toImmutableSetMultimap
— 創建一個ImmutableSetMultimap
Multimaps.toMultimap
— 使用給定的Supplier
創建一個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.