Java 8 Stream - 使用Custom Collector时出现NullPointerException

时间:2016-12-01 08:05:54

标签: java-8 java-stream collectors

我通过实现Collector接口并覆盖其方法来实现自定义收集器。收集器实现如下:

class MyCustomCollector implements Collector<Person, StringJoiner, String>{

    @Override
    public Supplier<StringJoiner> supplier() {
        // TODO Auto-generated method stub
        return () -> new StringJoiner("|");
    }

    @Override
    public BiConsumer<StringJoiner, Person> accumulator() {
        // TODO Auto-generated method stub
        return (joiner,person) -> joiner.add(person.name.toUpperCase());
    }

    @Override
    public BinaryOperator<StringJoiner> combiner() {
        // TODO Auto-generated method stub
        return (joiner1, joiner2) -> joiner1.merge(joiner2);
    }

    @Override
    public Function<StringJoiner, String> finisher() {
        // TODO Auto-generated method stub
        return StringJoiner::toString;
    }

    @Override
    public Set<java.util.stream.Collector.Characteristics> characteristics() {
        // TODO Auto-generated method stub
        return null;
    }
}

这是我的Person类:

class Person implements Comparable<Object>{
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name;
    }

    public int compareTo(Object obj){
        int returnValue;
        if(age ==((Person) obj).age)
            returnValue=0;
        else
            if(age >((Person) obj).age)
                returnValue = 1;
            else
                returnValue =-1;

        return returnValue;
    }

    public boolean equals(Object obj)
    {
        if(!(obj instanceof Person))
            return false;

        return (age == ((Person) obj).age); 
    }

    public int hashCode()
    {  
        return name.hashCode();  
    } 

}

这是我的主张声明......

List<Person> persons =
        Arrays.asList(
            new Person("Max", 18),
            new Person("Peter", 23),
            new Person("Pamela", 23),
            new Person("David", 12),
            new Person("Pam", 23));
String names2 = persons.stream()
            .collect(new MyCustomCollector());

当执行上述语句时,我得到一个NullPointerException,如下所示:

  

线程中的异常&#34; main&#34;显示java.lang.NullPointerException       在java.util.stream.ReduceOps $ 3.getOpFlags(ReduceOps.java:185)       at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)       在java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)       在com.my.j8.TestStreams.main(TestStreams.java:231)

有人可以告诉我哪里犯了错误吗?

1 个答案:

答案 0 :(得分:8)

下面:

public Set<java.util.stream.Collector.Characteristics> characteristics() {
    return null;

返回集而不是null;像

private final static Set<Characteristics> EMPTY = Collections.emptySet();

...

return EMPTY;

或只是

return Collections.emptySet();

(因为Collections类已经有了一些EMPTY常量)。

核心要点是:此接口包含该方法;并且“我没有使用这部分”仍然要求你“合理地”实现该方法。因此,请记住以后:任何集合返回界面都可以通过返回来说“无内容”;而不是 null 的东西!

当然,最后问题可以通过周围的框架而不是来检查该方法是否返回null。但正如所说:当你处理任何类型的集合时,忘记关于使用null。如果没有,请创建该类型的集合对象!

避免NPE的一个关键步骤是首先不返回 null。

除此之外:正如尤金所指出的那样 - 你可能想要仔细检查一下,如果真的应该在这里使用空套。换句话说:你是否研究过Characteristics并了解它们的整体概念;你是否100%肯定在这里想要“无”?!