I have read the topic:
Collectors.groupingBy doesn't accept null keys
But I don't understand how can I apply it for my issue:
my code:
Map<String, List<MappingEntry>> mappingEntryMap = mapping.getMappingEntries()
.stream()
.collect(Collectors.groupingBy(MappingEntry::getMilestone, Collectors.mapping(e -> e, Collectors.toList())));
For me MappingEntry::getMilestone
sometimes can return null. It is ok for my situation but I see:
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)
How can I avoid this exception?
Use Collectors.toMap
instead and specify that a HashMap
is used (as it allows one null key)
Collectors.toMap(
MappingEntry::getMilestone,
x -> {
List<MappingEntry> list = new ArrayList<>();
list.add(x);
return list;
},
(left, right) -> {
left.addAll(right);
return left;
},
HashMap::new
)
Given that you want to retain the MappingEntry
objects regardless of when getMilestone()
is null or non-null and knowing that a NullPointerException
will be thrown when a particular contract in not met then we can avoid that by using a replacement key to group the MappingEntry
objects which have a null milestone and yet group the other MappingEntry
objects as they're supposed to be.
Map<String, List<MappingEntry>> mappingEntryMap =
mapping.getMappingEntries()
.stream()
.collect(groupingBy(m -> m.getMilestone() == null ?
"absentMilestone" : m.getMilestone()));
The trick here is to use a ternary operator which provides a key to group all the MappingEntry
objects that have a absent milestone into a single group and if the milestone is not absent then we can group by its value as you'd expect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With