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