Map List to Map with additional transformation

Tags: ,



I need to convert a list of objects to a map of sets of one of the objects’ property and I’d like to use Java streams for that.

For example there is a List<Dog> and I’d like to convert it to a HashMap where key is dog age and value is Set of breeds.

@Getter //lombok for getters
public class Dog {
    private String name;
    private int age;
    private int breed;
}

I can create Map<Integer, Set<Dog>> dogsByAge a by using this statement.

Map<Integer, Set<Dog>> dogsByAge = dogs.stream()
                                       .collect(groupingBy(Dog::getAge, toSet()));

However I need Map<Integer, Set<String>> breedsByAge

Is that possible using streams?

Answer

The following should meet the requirement:

Map<Integer, Set<Integer>> breedsByAge = dogs.stream()
                .collect(Collectors.groupingBy(Dog::getAge, Collectors.mapping(Dog::getBreed, Collectors.toSet())));

Demo:

public class Main {
    public static void main(String[] args) {
        List<Dog> dogs = List.of(new Dog("A", 10, 1), new Dog("B", 5, 1), new Dog("C", 10, 2), new Dog("D", 10, 3),
                new Dog("E", 5, 4));

        Map<Integer, Set<Integer>> breedsByAge = dogs.stream()
                .collect(Collectors.groupingBy(Dog::getAge, Collectors.mapping(Dog::getBreed, Collectors.toSet())));

        System.out.println(breedsByAge);
    }
}

Output:

{5=[1, 4], 10=[1, 2, 3]}


Source: stackoverflow