我当前的尝试:
Map<Integer, Map<String, Integer>> collect = shopping.entrySet()
.stream()
.collect(Collectors.toMap/*groupingBy? */(e -> e.getKey().getAge(),
e -> e.getValue().entrySet().stream().collect(Collectors.groupingBy(b -> b.getKey().getCategory(), Collectors.summingInt(Map.Entry::getValue)))));
shopping
基本上是一张地图:Map<Client, Map<Product,Integer>>
问题出在以下事实:所提供的数据按键包含多个值-有些客户具有相同的年龄,并且代码仅按键对单个值起作用。
如何使此代码也可用于多个键?
我想应该以某种方式更改为使用collect collect(Collectors.groupingBy)
->
在结果映射Map<Integer, Map<String, Integer>>
中:
我尝试使用分组方式
Map<Integer, Map<String, Integer>> collect = shopping.entrySet()
.stream()
.collect(Collectors.groupingBy(/*...*/))
我只是想使用流将该代码重构为一个:
Map<Integer, Map<String, Integer>> counts = new HashMap<>();
for (Map.Entry<Client, Map<Product, Integer>> iData : shopping.entrySet()) {
int age = iData.getKey().getAge();
for (Map.Entry<Product, Integer> iEntry : iData.getValue().entrySet()) {
String productCategory = iEntry.getKey().getCategory();
counts.computeIfAbsent(age, (agekey) -> new HashMap<>()).compute(productCategory, (productkey, value) -> value == null ? 1 : value + 1);
}
}
答案 0 :(得分:2)
一种非流式(forEach
)转换for循环的方式可能是:
Map<Integer, Map<String, Integer>> counts = new HashMap<>();
shopping.forEach((key, value1) -> value1.keySet().forEach(product ->
counts.computeIfAbsent(key.getAge(),
(ageKey) -> new HashMap<>())
.merge(product.getCategory(), 1, Integer::sum)));
答案 1 :(得分:1)
通过groupingBy
收集器而不是toMap
更合适。
Map<Integer, Map<String, Integer>> result = shopping.entrySet()
.stream()
.collect(groupingBy(e -> e.getKey().getAge(),
flatMapping(e -> e.getValue().keySet().stream(),
groupingBy(Product::getCategory,
summingInt(e -> 1)))));
请注意,此方法使用flatMapping
,仅在jdk9以后的标准库中可用。