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}
私は好奇心を求めています。なぜ 'collect'の代わりに' reduce'を使用していますか?利点はありますか? – Flown
@Flownいいえ、それは本当に同じです。 'flatMap'の呼び出しは、タプルホルダーを持つ必要があるため、簡単ではありません(理解しにくいかもしれません)。 'reduce'は単に' for'ループのように読む代替の解決策に過ぎません。リストが非常に大きく、確かではないにもかかわらず、パフォーマンスに違いがあるかもしれません。 – Tunaki
質問は2番目のアプローチを対象としていました。私はOracleのチュートリアルで答えを見つけました。 'reduce'は不変で' collect'の変更可能な縮小で使われます。逐次実行においては、両方の減少が同じ挙動を示す。並列化された 'Stream'を使いたいのであれば' collect'を使うほうが良いでしょう:list.stream()。collect(HashMap :: new、(m、i) - > {m.merge(i.name1、i (m、m) - > m1.forEach((k、v) - > m2.merge) (k、v、Integer :: sum))) ' – Flown