この回答でA
は、List<A> listofA
リストの要素が繰り返された場合にどうなるかを示しています。
実際、に重複があるlistofA
場合、次のコードはをスローしIllegalStateException
ます。
Map<A, Collection<B>> resultMap = listofA.stream()
.collect(Collectors.toMap(
Function.identity(),
repo::getListofB);
キーに衝突がある場合(つまり、キーマッパー関数が重複を返す場合、リストに繰り返し要素がある場合など)に値Collectors.toMap
をマージする方法がわからないため、例外がスローされる可能性があります。Function.identity()
listofA
これはドキュメントで明確に述べられています:
マップされたキーに重複が含まれている場合(によるとObject.equals(Object)
)、IllegalStateException
コレクション操作が実行されるとがスローされます。マップされたキーが重複している可能性がある場合は、toMap(Function, Function, BinaryOperator
代わりに)を使用してください。
ドキュメントはまた、ソリューションを提供します。繰り返される要素がある場合、値をマージする方法を提供する必要があります。これがそのような方法の1つです。
Map<A, Collection<B>> resultMap = listofA.stream()
.collect(Collectors.toMap(
Function.identity(),
a -> new ArrayList<>(repo.getListofB(a)),
(left, right) -> {
left.addAll(right);
return left;
});
これは、3番目の引数としてマージ関数Collectors.toMap
を受け入れるオーバーロードされたバージョンを使用します。merge関数内で、を使用して、繰り返される各要素の要素を、それぞれのunqiueリストに追加しますCollection.addAll
B
A
A
ます。
値マッパー関数では、それぞれArrayList
のオリジナルが変更されないように、新しいものが作成されます。また、を作成しているので、それを変更できることを事前に知っています(つまり、に重複がある場合に備えて、後でそれに要素を追加できます)。List<B>
A
Arraylist
listofA
A
要素がありますList<A>
か?