reduce 的概念是否在Guava库中实现?我的意思是我有一个多图:
[1] -> 1, 2, 5, 8
[2] -> 3, 6, 4
[3] -> 1, 0
然后我有一个乘法函数:
(a, b) -> a * b
我想得到以下地图:
[1] -> 80 // 1 * 2 * 5 * 8
[2] -> 72 // 3 * 6 * 4
[3] -> 0 // 1 * 0
我如何在番石榴中做到这一点?
答案 0 :(得分:5)
我不认为番石榴有减少操作。我猜你有两个选择。
如果您正在使用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
会根据键值对条目进行分组。然后我们只是通过首先将它们映射到它们的值并最后将它们相乘来减少分组的值(Entry<Integer, Integer>
) - 为乘法提供1的标识值。
<小时/> 如果您无法使用java-8,则可以使用
Map<Integer, Collection<Integer>>
从Multimap
取回Multimaps.asMap
并使用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;
}
});
答案 1 :(得分:1)
使用String
键和List<Integer>
作为值。
您也可以尝试类似
的内容 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);
结果: {a = 6,b = 120}
答案 2 :(得分:0)
最简单的方法就是使用entries()
上的流,并在其上映射一个函数,将函数转换为流并在其上运行合适的reduce()
函数。
这样的事情:
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);