私はトピックを読みました:
Collectors.groupingByはnullキーを受け入れません
しかし、私はそれを私の問題にどのように適用できるのか理解していません:
私のコード:
Map<String, List<MappingEntry>> mappingEntryMap = mapping.getMappingEntries()
.stream()
.collect(Collectors.groupingBy(MappingEntry::getMilestone, Collectors.mapping(e -> e, Collectors.toList())));
私のために MappingEntry::getMilestone
はnullを返すことがあります。私の状況では問題ありませんが、次のように表示されます。
Caused by: Java.lang.NullPointerException: element cannot be mapped to a null key
at Java.util.Objects.requireNonNull(Objects.Java:228)
at Java.util.stream.Collectors.lambda$groupingBy$45(Collectors.Java:907)
at Java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.Java:169)
at Java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.Java:1374)
at Java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.Java:481)
at Java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.Java:471)
at Java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.Java:708)
at Java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.Java:234)
at Java.util.stream.ReferencePipeline.collect(ReferencePipeline.Java:499)
この例外を回避するにはどうすればよいですか?
使用する Collectors.toMap
代わりに、HashMap
が使用されることを指定します(1つのnullキーを許可するため)
Collectors.toMap(
MappingEntry::getMilestone,
x -> {
List<MappingEntry> list = new ArrayList<>();
list.add(x);
return list;
},
(left, right) -> {
left.addAll(right);
return left;
},
HashMap::new
)
getMilestone()
がnullまたはnon-nullであるかどうかに関係なくMappingEntry
オブジェクトを保持し、NullPointerException
は、特定の契約が満たされていない場合にスローされます。置換キーを使用してnullマイルストーンを持つMappingEntry
オブジェクトをグループ化し、さらにその他のMappingEntry
オブジェクトは、本来あるべきものです。
Map<String, List<MappingEntry>> mappingEntryMap =
mapping.getMappingEntries()
.stream()
.collect(groupingBy(m -> m.getMilestone() == null ?
"absentMilestone" : m.getMilestone()));
ここでの秘訣は、absentマイルストーンを持つすべてのMappingEntry
オブジェクトを単一のグループにグループ化するためのキーを提供する三項演算子を使用することです。マイルストーンがない場合は、期待どおりに値でグループ化します。
これに_Collector.of
_メソッドを使用してカスタムコレクターを指定し、結果のマップにHashMap
を使用できます。これは、HashMap
の_Java-8
_ docsによると
[...] null値とnullキーを許可します。 [...]
_Collector.of(
HashMap::new,
(map, e) -> map.computeIfAbsent(e.getMileStone(), k -> new ArrayList<>()).add(e),
(left, right) -> {
right.forEach((key,list) -> left.computeIfAbsent(key, k -> new ArrayList<>()).addAll(list));
return left;
})
)
_