Cleanest way to create a Guava Multimap from a Java 8 stream(从 Java 8 流创建 Guava Multimap 的最简洁方法)
问题描述
我有一个 List<Foo> 并且想要一个 MultimapFoo 分组的地方他们的 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 循环来创建我的 多地图.有没有一个不错的功能性"?我错过了什么?
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:
ImmutableMultimap<String, Foo> foosById = Multimaps.index(foos, Foo::getId);
或调用 Multimaps.index 带有 Collector 接口(如下所示,在未优化的幼稚实现中).
or wrap a call to Multimaps.index with a Collector<T, A, R> 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);
}
}
这篇关于从 Java 8 流创建 Guava Multimap 的最简洁方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从 Java 8 流创建 Guava Multimap 的最简洁方法
基础教程推荐
- Java Swing计时器未清除 2022-01-01
- 从 python 访问 JVM 2022-01-01
- 如何在 Spring @Value 注解中正确指定默认值? 2022-01-01
- 大摇大摆的枚举 2022-01-01
- 验证是否调用了所有 getter 方法 2022-01-01
- 不推荐使用 Api 注释的描述 2022-01-01
- Java 实例变量在两个语句中声明和初始化 2022-01-01
- 在 Java 中创建日期的正确方法是什么? 2022-01-01
- 多个组件的复杂布局 2022-01-01
- 如何在 JFrame 中覆盖 windowsClosing 事件 2022-01-01
