Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8 Java 8流-使用自定义收集器时出现NullPointerException_Java 8_Java Stream_Collectors - Fatal编程技术网

Java 8 Java 8流-使用自定义收集器时出现NullPointerException

Java 8 Java 8流-使用自定义收集器时出现NullPointerException,java-8,java-stream,collectors,Java 8,Java Stream,Collectors,通过实现收集器接口并重写其方法,我实现了一个自定义收集器。收集器实现如下所示: class MyCustomCollector implements Collector<Person, StringJoiner, String>{ @Override public Supplier<StringJoiner> supplier() { // TODO Auto-generated method stub return ()

通过实现收集器接口并重写其方法,我实现了一个自定义收集器。收集器实现如下所示:

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;
    }
}
类MyCustomCollector实现收集器{
@凌驾
公共供应商(){
//TODO自动生成的方法存根
return()->newstringjoiner(“|”);
}
@凌驾
公共双消费者累加器(){
//TODO自动生成的方法存根
return(joiner,person)->joiner.add(person.name.toUpperCase());
}
@凌驾
公共二进制运算符组合器(){
//TODO自动生成的方法存根
return(joiner1,joiner2)->joiner1.merge(joiner2);
}
@凌驾
公共函数完成器(){
//TODO自动生成的方法存根
返回StringJoiner::toString;
}
@凌驾
公共集特征(){
//TODO自动生成的方法存根
返回null;
}
}
这是我的个人课:

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();  
    } 

}
class-Person实现可比性{
字符串名;
智力年龄;
Person(字符串名称,整数年龄){
this.name=名称;
这个。年龄=年龄;
}
@凌驾
公共字符串toString(){
返回名称;
}
公共整数比较(对象对象对象){
返回值;
如果(年龄==((人)对象)。年龄)
返回值=0;
其他的
如果(年龄>((人)对象)年龄)
返回值=1;
其他的
返回值=-1;
返回值;
}
公共布尔等于(对象obj)
{
如果(!(人的obj实例))
返回false;
返回(年龄==((人)对象)。年龄);
}
公共int hashCode()
{  
返回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());
列出人员=
Arrays.asList(
新人(“Max”,18岁),
新人(“彼得”,23岁),
新人(“帕梅拉”,23岁),
新人(“大卫”,12岁),
新人(“Pam”,23));
字符串名称2=persons.stream()
.collect(新的MyCustomCollector());
当执行上述语句时,我得到一个NullPointerException,如下所示:

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;
    }
}
线程“main”java.lang.NullPointerException中出现异常 位于java.util.stream.ReduceOps$3.getOpFlags(ReduceOps.java:185) 位于java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 位于java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) 位于com.my.j8.TestStreams.main(TestStreams.java:231)

有人能告诉我哪里出了错吗?

这里:

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

return Collections.emptySet();
(因为Collections类本身已经有一些空常量)

核心点是:此接口包含该方法;“我不使用此部分”仍然要求您“合理地”实施该方法。因此,今后要记住这一点:任何集合返回接口都允许通过返回一个空的对象来表示“无内容”;而不是一个空的东西

当然,最终问题可以通过周围的框架not检查该方法是否返回null来发现。但正如前面所说:当您处理任何类型的集合时,忘记使用null。如果没有,请创建该类型的集合对象

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


除此之外:正如尤金所指出的,你可能想仔细检查一下,你是否真的应该使用一个空的集合。换言之:你是否研究并理解了它们的整个概念;你百分之百确定你不想在这里出现吗

请参阅我的最新答案。既然这个答案有帮助,请考虑接受。@ GhostCat,在没有提供任何特征之前,你应该认真地考虑这个问题。基于这些,在内部执行了不同的优化,没有提供任何可能会破坏这些优化的内容。@Eugene我的重点是帮助他的NPE;但你是对的;在这方面我加强了我的回答。@KaranVerma向我们引用javadoc没有多大意义。问题是:这是你的项目,你的代码;你想使用这个接口,所以你自己必须决定你想在这里做什么。如果你真的不理解这些价值观的含义;考虑下一个问题。不需要将<代码> SET/CODE >存储到变量中。code>Collections.emptySet()已返回存储在
Collections.EMPTY\u SET
中的常量。提示:从程序中查找
null
开始。GhostCat我根本没有这样做。感谢您的快速反馈!
return Collections.emptySet();