In Java 8, this works:
Stream stream = Stream.of(ArrayList.class);
HashMap> map = (HashMap)stream.collect(Collect
I figured I would take a moment and try to digest this issue you have. I put together a SSCE for what I would expect if I did it manually, and what the groupingBy implementation actually does.
I don't think this is an answer, but it is a 'wonder why it is a problem' thing. Also, if you want, feel free to hack this code to have a null-friendly collector.
Edit: A generic-friendly implementation:
/** groupingByNF - NullFriendly - allows you to specify your own Map and List supplier. */
private static final Collector>> groupingByNF (
final Supplier
Consider this code (the code groups String values based on the String.length(), (or null if the input String is null)):
public static void main(String[] args) {
String[] input = {"a", "a", "", null, "b", "ab"};
// How we group the Strings
final Function classifier = (a) -> {return a != null ? Integer.valueOf(a.length()) : null;};
// Manual implementation of a combiner that accumulates a string value based on the classifier.
// no special handling of null key values.
BiConsumer>, String> combiner = (m, v) -> {
Integer key = classifier.apply(v);
List store = m.get(key);
if (store == null) {
store = new ArrayList();
m.put(key, store);
}
store.add(v);
};
// The finalizer merges two maps together (right into left)
// no special handling of null key values.
BinaryOperator>> finalizer = (left, right) -> {
for (Map.Entry> me : right.entrySet()) {
List target = left.get(me.getKey());
if (target == null) {
left.put(me.getKey(), me.getValue());
} else {
target.addAll(me.getValue());
}
}
return left;
};
// Using a manual collector
Map> manual = Arrays.stream(input).collect(Collector.of(HashMap::new, combiner, finalizer));
System.out.println(manual);
// using the groupingBy collector.
Collector>> collector = Collectors.groupingBy(classifier);
Map> result = Arrays.stream(input).collect(collector);
System.out.println(result);
}
The above code produces the output:
{0=[], null=[null], 1=[a, a, b], 2=[ab]} Exception in thread "main" 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$135(Collectors.java:907) at java.util.stream.Collectors$$Lambda$10/258952499.accept(Unknown Source) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) 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) at CollectGroupByNull.main(CollectGroupByNull.java:49)