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