KayV
KayV

Reputation: 13855

Java 8 Stream - NullPointerException when working with Custom Collector

I have implemented a custom collector by implementing the Collector interface and overridding its methods. The Collector implementation is as follows:

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

Here is my Person class:

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

}

And Here is my calling statements...

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

When the above statement gets executed, i got a NullPointerException as follows:

Exception in thread "main" java.lang.NullPointerException at java.util.stream.ReduceOps$3.getOpFlags(ReduceOps.java:185) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at com.my.j8.TestStreams.main(TestStreams.java:231)

Can anybody tell where i am making the mistake?

Upvotes: 2

Views: 1599

Answers (1)

GhostCat
GhostCat

Reputation: 140613

Here:

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

Return an empty set instead of null; like

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

...

return EMPTY;

or just

return Collections.emptySet();

(as the Collections class is already having some EMPTY constant on its own).

The core point is: this interface contains that method; and "I am not using this part" still requires you to "reasonably" implement that method. So keep that in mind for the future: any collection-returning interface allows for saying "no content" by returning an empty thing; instead of a null thing!

Of course, in the end the problem could be seen by the surrounding framework not checking if that method returns null. But as said: when you are dealing with collections of any kind, forget about using null. If there is nothing, create an empty collection object of that type!

One crucial step to avoid NPEs is by not returning null in the first place.

And beyond that: as Eugene is pointing out - you probably want to check really carefully of if you really should go with an empty Set here. In other words: did you look into Characteristics and do understand the whole concept of them; and are you 100% sure that want "none" here?!

Upvotes: 8

Related Questions