このコードを見てください。
// group by price, uses 'mapping' to convert List<Item> to Set<String>
Map<BigDecimal, Set<String>> result =
items.stream().collect(
Collectors.groupingBy(Item::getPrice,
Collectors.mapping(Item::getName, Collectors.toSet())
)
);
GroupingByとMappingは交換可能ですか?それらの違いは何ですか?
Collect()の3番目のパラメーターで、Collectors.toSet()の代わりにCollectors.toList()を使用した場合、同じ出力タイプMapを取得できますか? toList()がより人気のあるオプションだと聞きました。
GroupingByとMappingは交換可能ですか?
いいえ、まったく異なります。 groupingBy
を使用すると、Map
を作成できます。ここで、キーはgroupingBy
に渡される最初の引数であり、値はList
の要素タイプのStream
です。
Collectors.groupingBy(Item::getPrice)
は_Map<BigDecimal, List<Item>>
_を生成します(_Item::getPrice
_がBigDecimal
を返すと仮定します。mapping
Collector
をCollectors.groupingBy()
に引数として渡すと、出力の値を変更できますマップ(あなたの例では、それを_Set<String>
_に変更します)。
Collect()の3番目のパラメーターで、Collectors.toSet()の代わりにCollectors.toList()を使用した場合、同じ出力タイプMapを取得できますか?
いいえ、_Map<BigDecimal, List<String>>
_を取得します。
いいえ、2つは完全に異なります。
_Collectors.groupingBy
_は、キーを作成し、キーから同じキーを持つストリーム内のオブジェクトのコレクションへのマップを返すコレクターを返す関数を取ります。
一方、_Collectors.mapping
_は、関数と別のコレクターを受け取り、新しいコレクターを作成します。このコレクターは、最初に関数を適用し、次に指定されたコレクターを使用してマップされた要素を収集します。したがって、以下は同等です。
_items.stream().map(f).collect(c);
items.stream().collect(Collectors.mapping(f, c));
_
_Collectors.mapping
_は、ストリームがなくてもコレクターを直接渡す必要がある場合に最も役立ちます。そのような状況の例は、_Collectors.groupingBy
_を使用する場合です。
_items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.toSet()))
_
_Map<BigDecimal,Set<Item>>
_を生成します(getPrice()
がBigDecimal
を返すと仮定)。しかしながら、
_items.stream().collect(Collectors.groupingBy(Item::getPrice,
Collectors.mapping(Item::getName, Collectors.toSet())))
_
_Map<BigDecimal,Set<String>>
_を返します。アイテムを収集する前に、まず_Item.getName
_を適用します。