web-dev-qa-db-ja.com

NullPointerException:要素をnullキーにマップできません

私はトピックを読みました:

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)

この例外を回避するにはどうすればよいですか?

9
gstackoverflow

使用する 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

)
10
Eugene

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オブジェクトを単一のグループにグループ化するためのキーを提供する三項演算子を使用することです。マイルストーンがない場合は、期待どおりに値でグループ化します。

3
Ousmane D.

これに_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;
     })
)
_
1
Lino