我通过实现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)
有人可以告诉我哪里犯了错误吗?
答案 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%肯定在这里想要“无”?!