番石榴:如何定制减少多图?

Den*_*gin 6 java guava

是否在Guava库中实现了reduce的概念?我的意思是我有一个multimap:

[1] -> 1, 2, 5, 8
[2] -> 3, 6, 4
[3] -> 1, 0
Run Code Online (Sandbox Code Playgroud)

然后我有一个乘法函数:

(a, b) -> a * b
Run Code Online (Sandbox Code Playgroud)

我想得到以下地图:

[1] -> 80          // 1 * 2 * 5 * 8
[2] -> 72          // 3 * 6 * 4
[3] -> 0           // 1 * 0
Run Code Online (Sandbox Code Playgroud)

我怎么在番石榴呢?

Ale*_* C. 5

我不认为番石榴有减少操作.我想你有两个选择.

如果您使用,刚刚流过的条目集,并收集项目与新的地图groupingByreduce.

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)));
Run Code Online (Sandbox Code Playgroud)

groupingBy您可以猜测,它会按照键值对条目进行分组.然后我们Entry<Integer, Integer>通过首先将它们映射到它们的值并最终乘以它们来减少分组的值(它们) - 为乘法提供1的标识值.


如果你无法使用,你可以得到一个Map<Integer, Collection<Integer>>从你MultimapMultimaps.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;
            }
        });
Run Code Online (Sandbox Code Playgroud)


chi*_*ity 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);
Run Code Online (Sandbox Code Playgroud)