Collectors.groupingBy不接受空键 [英] Collectors.groupingBy doesn't accept null keys

查看:9809
本文介绍了Collectors.groupingBy不接受空键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java 8中,这是可行的:

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

但这不是:

 流<类> stream = Stream.of(List.class); 
HashMap< Class,List< Class>> map =(HashMap)stream.collect(Collectors.groupingBy(Class :: getSuperclass));

地图允许空键,而List.class.getSuperclass()返回空。但Collectors.groupingBy在Collectors.java第907行发出NPE:

  K key = Objects.requireNonNull(classifier.apply (t),元素不能映射到空键); 

如果我创建了自己的收藏夹,此行更改为:

  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& (<> newEl) - > {
List< Class<> newList = new ArrayList<>(oldList.size()+1);
newList.addAll (oldList);
newList.addAll(newEl);
return newList;
}));

或者封装它:

  / **与Collectors.groupingBy类似,但接受空键。 * / 
public static< T,A>收集器< T,?,Map< A,List< T>>>
groupingBy_WithNullKeys(函数< ;? super T,?extends A>分类器){
返回Collectors.toMap(
分类符,
Collections :: singletonList,
(List< (oldList),oldList(newList),newList(newList),newListList(newListList)。
newList.addAll(newEl);
return newList;
});
}

并像这样使用它:

  Stream< Class<>> stream = Stream.of(ArrayList.class); 
Map< Class<>,List< Class<>>> map = stream.collect(groupingBy_WithNullKeys(Class :: getSuperclass));

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

In Java 8, this works:

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

But this doesn't:

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

Maps allows a null key, and List.class.getSuperclass() returns null. But Collectors.groupingBy emits a NPE, at Collectors.java, line 907:

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

It works if I create my own collector, with this line changed to:

K key = classifier.apply(t);  

My questions are:

1) The Javadoc of Collectors.groupingBy doesn't say it shouldn't map a null key. Is this behavior necessary for some reason?

2) Is there another, easier way, to accept a null key, without having to create my own collector?

解决方案

For the first question, I agree with skiwi that it shouldn't be throwing a NPE. I hope they will change that (or else at least add it to the javadoc). Meanwhile, to answer the second question I decided to use Collectors.toMap instead of 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;
        }));

Or, encapsulating it:

/** 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;
            });
    }

And use it like this:

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

Please note rolfl gave another, more complicated answer, which allows you to specify your own Map and List supplier. I haven't tested it.

这篇关于Collectors.groupingBy不接受空键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆