Collectors.groupingBy不接受空键

在Java 8中,这有效:

Stream<Class> stream = Stream.of(ArrayList.class);

HashMap<Class, List<Class>> map = (HashMap)stream.collect(Collectors.groupingBy(Class::getSuperclass));

但这不是:

Stream<Class> stream = Stream.of(List.class);

HashMap<Class, List<Class>> map = (HashMap)stream.collect(Collectors.groupingBy(Class::getSuperclass));

Maps允许使用null键,并且List.class.getSuperclass()返回null。但是Collectors.groupingBy在Collectors.java的第907行发出了NPE:

K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");

如果我创建自己的收集器,则此行会更改为:

K key = classifier.apply(t);

我的问题是:

1)Collectors.groupingBy的Javadoc并未表示不应映射空键。是否出于某种原因需要这种行为?

2)是否有另一种更简单的方法来接受空键,而无需创建自己的收集器?

回答:

对于第一个问题,我同意skiwi的观点,即它不应该抛出NPE。我希望他们能够对此进行更改(或者至少将其添加到javadoc中)。同时,为了回答第二个问题,我决定使用Collectors.toMap代替Collectors.groupingBy

Stream<Class<?>> stream = Stream.of(ArrayList.class);

Map<Class<?>, List<Class<?>>> map = stream.collect(

Collectors.toMap(

Class::getSuperclass,

Collections::singletonList,

(List<Class<?>> oldList, List<Class<?>> newEl) -> {

List<Class<?>> newList = new ArrayList<>(oldList.size() + 1);

newList.addAll(oldList);

newList.addAll(newEl);

return newList;

}));

或者,将其封装:

/** Like Collectors.groupingBy, but accepts null keys. */

public static <T, A> Collector<T, ?, Map<A, List<T>>>

groupingBy_WithNullKeys(Function<? super T, ? extends A> classifier) {

return Collectors.toMap(

classifier,

Collections::singletonList,

(List<T> oldList, List<T> newEl) -> {

List<T> newList = new ArrayList<>(oldList.size() + 1);

newList.addAll(oldList);

newList.addAll(newEl);

return newList;

});

}

并像这样使用它:

Stream<Class<?>> stream = Stream.of(ArrayList.class);

Map<Class<?>, List<Class<?>>> map = stream.collect(groupingBy_WithNullKeys(Class::getSuperclass));

请注意,rolfl给出了另一个更复杂的答案,该答案使您可以指定自己的地图和列表供应商。我还没有测试。

以上是 Collectors.groupingBy不接受空键 的全部内容, 来源链接: utcz.com/qa/434667.html

回到顶部