将List<>映射为Map<Integer, Set>并进行额外的转换

3
我需要将一组对象转换为一个映射,该映射的键是对象属性中的某个唯一值,并且我想使用Java流进行转换。
例如,有一个 `List`,我想将其转换为一个 `HashMap`,其中键是狗的年龄,值是品种的 `Set`。
@Getter //lombok for getters
public class Dog {
    private String name;
    private int age;
    private int breed;
}

我可以使用这个语句创建一个Map<Integer, Set<Dog>> dogsByAge对象。
Map<Integer, Set<Dog>> dogsByAge = dogs.stream()
                                       .collect(groupingBy(Dog::getAge, toSet()));

然而我需要 Map<Integer, Set<String>> breedsByAge

使用流操作能实现这个吗?


这是完全有可能的,但看起来你没有足够的属性来确保唯一性...你很容易会有两个具有相同年龄、名字和品种的“Dog”。请展示完整的“Dog”类,包括“hashCode()”和“equals()”方法(你有这些方法吧?)。 - Jim Garrison
1
groupingBy(Dog::getAge, Collectors.mapping(Dog::getBreed, toSet)) - Eugene
@JimGarrison 我不需要唯一性,集合的重点是避免结果中出现重复的品种。@Data 不是一个很好的选择,应该使用 @Getter - Michal Krasny
1个回答

6
以下应该符合要求:
Map<Integer, Set<Integer>> breedsByAge = dogs.stream()
                .collect(Collectors.groupingBy(Dog::getAge, Collectors.mapping(Dog::getBreed, Collectors.toSet())));

演示:

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

输出:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接