Michiel
Michiel

Reputation: 113

Java streams to map

I'm having a problem with the Map<Integer, List<String>> personenPerLeeftijd, the compiler says the method, Persoon::getLeeftijd, cannot be resolved. I don't really know what else I can do, sorry for the Dutch words!

I you need any more info pls ask so

public class TestPersoon2 {
public static void main(String[] args) {

    final List<Persoon> personen = Personen.getPersonen();


    Map<String, Persoon> map =
            personen.stream().collect(Collectors.toMap(p -> p.getNaam() + "-" + p.getLeeftijd(), p -> p));
    for (String s : map.keySet()) {
        System.out.printf("%-15s -> %s\n", s, map.get(s));
    }
    Map<Integer, List<String>> personenPerLeeftijd =
            personen.stream().collect(Collectors.groupingBy(Persoon::getLeeftijd)); //THIS METHOD


    personenPerLeeftijd.forEach((k, v) -> System.out.printf("%2d: %s\n", k,
            v.stream()


            System.out.println();

    TreeMap<Integer, Long> perLeeftijd =
            personen.stream().collect(Collectors.groupingBy(Persoon::getLeeftijd, Collectors.counting()));


    perLeeftijd.forEach((k, v) -> System.out.printf("%2d -> %d\n", k, v));
}

Persoon class

public class Persoon {
private final String naam;
private final Geslacht geslacht;
private final int leeftijd;

public Persoon(String naam, Geslacht geslacht, int leeftijd) {
    this.naam = naam;
    this.geslacht = geslacht;
    this.leeftijd = leeftijd;
}

public String getNaam() {
    return naam;
}

public Geslacht getGeslacht() {
    return geslacht;
}

public int getLeeftijd() {
    return leeftijd;
}

public int leeftijdsverschil(final Persoon andere) {
    return leeftijd - andere.leeftijd;
}

@Override
public String toString() {
    return String.format("%-9s - %s - %2d", naam, geslacht, leeftijd);
}

Upvotes: 2

Views: 763

Answers (1)

OldCurmudgeon
OldCurmudgeon

Reputation: 65793

As mentioned by @luk2302, the easiest solution is to use Map<Integer, List<Person>>.

    Map<Integer, List<Person>> peopleByAge = personen
            .stream()
            .collect(Collectors.groupingBy(Person::getAge)); //THIS METHOD

If you really need Map<Integer, List<String>> then there's a little more to do.

    Map<Integer, List<String>> peoplesNamesByAge = personen
            .stream()
            .collect(
                    Collectors.groupingBy(Person::getAge,
                            Collectors.mapping(Person::getName,
                                    Collectors.toList())));
    peoplesNamesByAge.forEach((k, v) -> System.out.printf("%2d: %s\n", k, v));

Here's the whole thing - I've anglicised it a little for my own sanity. :)

enum Gender {

    Male, Female;
}

public class Person {

    private final String name;
    private final Gender gender;
    private final int age;

    public Person(String naam, Gender gender, int age) {
        this.name = naam;
        this.gender = gender;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Gender getGender() {
        return gender;
    }

    public int getAge() {
        return age;
    }

    public int getAgeDifference(final Person other) {
        return age - other.age;
    }

    @Override
    public String toString() {
        return String.format("%-9s - %s - %2d", name, gender, age);
    }
}

public void test() {
    final List<Person> personen = Personen.getPersonen();

    Map<String, Person> map
            = personen.stream().collect(Collectors.toMap(p -> p.getName() + "-" + p.getAge(), p -> p));
    for (String s : map.keySet()) {
        System.out.printf("%-15s -> %s\n", s, map.get(s));
    }
    Map<Integer, List<Person>> peopleByAge = personen
            .stream()
            .collect(Collectors.groupingBy(Person::getAge)); //THIS METHOD

    peopleByAge.forEach((k, v) -> System.out.printf("%2d: %s\n", k, v));

    Map<Integer, List<String>> peoplesNamesByAge = personen
            .stream()
            .collect(
                    Collectors.groupingBy(Person::getAge,
                            Collectors.mapping(Person::getName,
                                    Collectors.toList())));
    peoplesNamesByAge.forEach((k, v) -> System.out.printf("%2d: %s\n", k, v));

    System.out.println();

    // TreeMap<Integer, Long> perLeeftijd
    Map<Integer, Long> perLeeftijd = personen
            .stream()
            .collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));

    perLeeftijd.forEach((k, v) -> System.out.printf("%2d -> %d\n", k, v));
}

Upvotes: 2

Related Questions