4
我需要创建具有name1/2求和值value1/2的键的地图。Java 8流减少和组合列表项到地图
什么可能是最简洁的方式来重写这个使用java 8流?
class Item {
private String name1;
private Integer value1;
private String name2;
private Integer value2;
public Item(final String name1, final Integer value1, final String name2, final Integer value2) {
this.name1 = name1;
this.value1 = value1;
this.name2 = name2;
this.value2 = value2;
}
//getters and setters
}
List<Item> list = Lists.newArrayList(
new Item("aaa", 1, "bbb", 2),
new Item("bbb", 5, "ccc", 3),
new Item("aaa", 8, "bbb", 7),
new Item("bbb", 2, "aaa", 5));
Map<String, Integer> map = Maps.newHashMap();
for (Item item : list) {
map.merge(item.name1, item.value1, Integer::sum);
map.merge(item.name2, item.value2, Integer::sum);
}
System.out.println(map);//{aaa=14, ccc=3, bbb=16}
我只是在问好奇。你为什么使用'reduce'而不是'collect'?有什么优势吗? – Flown
@Flown不,它真的是一样的。 'flatMap'调用并不是那么简单,因为必须有一个元组持有者(所以可能更难理解)。 'reduce'只是一种替代解决方案,它更像'for'循环。虽然列表相当大,但不确定,但表现可能有所不同。 – Tunaki
问题是针对你的第二种方法,我在Oracle教程中找到了答案。 'reduce'用于不可变的和'collect'可变的缩减。在顺序执行中,两个缩减都显示相同的行为。如果你想使用并行化的'Stream',最好使用'collect':'list.stream()。collect(HashMap :: new,(m,i) - > {m.merge(i.name1,i (k,v) - > m2.merge().value1,Integer :: sum); m.merge(i.name2,i.value2,Integer :: sum);},(m1,m2) - > m1.forEach (k,v,Integer :: sum)))' – Flown