[英]Guava: how to customly reduce a multimap?
Is the concept of reduce implemented in Guava libs? 是否在Guava库中实现了reduce的概念? I mean I have a multimap:
我的意思是我有一个multimap:
[1] -> 1, 2, 5, 8
[2] -> 3, 6, 4
[3] -> 1, 0
Then I have a multiplying function : 然后我有一个乘法函数 :
(a, b) -> a * b
And I want to get the following map: 我想得到以下地图:
[1] -> 80 // 1 * 2 * 5 * 8
[2] -> 72 // 3 * 6 * 4
[3] -> 0 // 1 * 0
How do I do it in Guava? 我怎么在番石榴呢?
I don't think there is a reduction operation in Guava. 我不认为番石榴有减少操作。 I guess you have two options.
我想你有两个选择。
If you're using java-8 , just stream over the entry set, and collect the entries into a new map with groupingBy
and reduce
. 如果您正在使用java-8 ,只需在条目集上流式传输,并使用
groupingBy
和reduce
将条目收集到新地图中。
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.reducing;
...
Map<Integer, Integer> map =
multimap.entries()
.stream()
.collect(groupingBy(Map.Entry::getKey,
reducing(1, Map.Entry::getValue, (a, b) -> a * b)));
groupingBy
as you can guess, will group the entries by their key values. groupingBy
,你可以猜测,将按照键值对条目进行groupingBy
。 Then we just reduce the values grouped (which are Entry<Integer, Integer>
) by first mapping their to their values and finally by multiplying them - providing the identity value which is 1 for the multiplication. 然后我们只是通过首先将它们映射到它们的值并最后将它们相乘来减少分组的值(即
Entry<Integer, Integer>
) - 为乘法提供1的标识值。
Map<Integer, Collection<Integer>>
from your Multimap
with Multimaps.asMap
and use Maps.transformValues
:
Multimaps.asMap
从Multimap
获取Map<Integer, Collection<Integer>>
并使用Maps.transformValues
:
Map<Integer, Collection<Integer>> tempMap = Multimaps.asMap(oldMap); Map<Integer, Integer> newMap = Maps.transformValues(tempMap, new Function<Collection<Integer>, Integer>() { @Nullable @Override public Integer apply(Collection<Integer> input) { //do the multiplication here return 0; } });
Used String
key and List<Integer>
as values. 使用
String
键和List<Integer>
作为值。
You can also try something like 你也可以尝试类似的东西
Map<String, List<Integer>> test = new HashMap<String, List<Integer>>();
test.put("a", Lists.newArrayList(1, 2, 3));
test.put("b", Lists.newArrayList(4, 5, 6));
Map<String, Integer> transformEntries = Maps.transformEntries(test, new EntryTransformer<String, List<Integer>, Integer>() {
@Override
public Integer transformEntry(String key, List<Integer> values) {
Integer a = 1;
for (Integer value : values) {
a = value * a;
}
return a;
}
});
System.out.println(transformEntries);
Result : {a=6, b=120} 结果:{a = 6,b = 120}
The easiest way looks like using a stream over entries()
, and mapping a function over it that converts the collection to a stream and runs a suitable reduce()
function over that. 最简单的方法是在
entries()
使用流,并在其上映射一个函数,将函数转换为流并运行一个合适的reduce()
函数。
Something like this: 像这样的东西:
HashMap<Integer, Integer> collected =
mmap.entries().stream().collect(HashMap::new,
(map, e) -> {
map.put(e.getKey(), e.getValue().stream().reduce((a, b) -> (a * b)).get());
}, HashMap::putAll);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.