0

I want to use the stream api sorting with a Comparator parameter but it doesn't sort properly. I always get exception.

I want to sort an object with a reference to another object, and the referenced object has a String so I want to sort it to its length.

This is my main method.

List<Person> liste = Arrays.asList(new Person(new Info("akin"))
                                  ,new Person(new Info("lars"))
                                  ,new Person(new Info("aaa")));

liste.stream()
     .map(p -> p.f)
     .map(f -> f.name)
     .sorted((s,s2) -> s.length() - s2.length())
     .forEach(System.out::print);
Dino
  • 7,779
  • 12
  • 46
  • 85
bratan
  • 1
  • 1
  • What kind of exception do you get? – MC Emperor Jul 31 '19 at 10:13
  • Exception in thread "main" java.lang.NullPointerException at MainStart.lambda$main$0(MainStart.java:43) ….. – bratan Jul 31 '19 at 10:19
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – MC Emperor Jul 31 '19 at 10:20
  • is it because it is an optional method? – bratan Jul 31 '19 at 10:24
  • @bratan without the complete details of the actual code that you're executing with, it's tough to say why it would result in a `NullPointerException`. Though you've got to still check the values of `person`, `info` and `name` for each object should not be `null`, that is where the exception could arise from. – Naman Jul 31 '19 at 10:40
  • yeah i tried it with integer and it works but with string it dont work, dont know why – bratan Jul 31 '19 at 10:55

1 Answers1

1

I'll make an assumption here because your stream code looks good.

I assume that in at least one of the two constructors (either for Person or for Info) you didn't assign the incoming value properly to the instance field, hence it is null and trying to get f.name or [f.name].length() will lead to a NullPointerException.

Below is a working example of the stream that you posted (you will notice, I did not change anything in the code in your question except for some indentation).

import java.util.Arrays;
import java.util.List;

class Main {

    public static void main(String[] args) {
        List<Person> liste = Arrays.asList(new Person(new Info("akin")),
                new Person(new Info("lars")),
                new Person(new Info("aaa")));

        liste.stream()
                .map(p -> p.f)
                .map(f -> f.name)
                .sorted((s, s2) -> s.length() - s2.length())
                .forEach(System.out::print);
    }

    static class Person {
        Info f;

        public Person(Info f) {
            this.f = f;
        }
    }

    static class Info {
        String name;

        public Info(String name) {
            this.name = name;
        }
    }

}

Your constructor might look like

public Person(Info f) {
    f = f;
}

(notice the missing this compared to my example). This is a good read on uses of this.

My IDE also suggested a minor change on the sorted method. You can use Comparator#comparingInt which would look like this:

.sorted(Comparator.comparingInt(String::length))

This really comes down to what you think is more readable though.

For further reference on NullPointerExceptions please read the link that was already posted in the comments. This won't have been your last one ;)