gpt4 book ai didi

java - 在 java 中的 Collectors.groupingBy 之后展平 map

转载 作者:搜寻专家 更新时间:2023-10-31 08:18:43 24 4
gpt4 key购买 nike

我有学生名单。我想返回包含该类(class)的 StudentResponse 类对象列表和该类(class)的学生列表。所以我可以写 which gives me a map

Map<String, List<Student>> studentsMap = students.stream().
.collect(Collectors.groupingBy(Student::getCourse,
Collectors.mapping(s -> s, Collectors.toList()
)));

现在我必须再次遍历 map 以创建 StudentResponse 类的对象列表,其中包含 Course 和 List:

class StudentResponse {
String course;
Student student;

// getter and setter
}

有没有办法结合这两个迭代?

最佳答案

不完全是你问的,但这里有一个紧凑的方法来完成你想要的,只是为了完整性:

Map<String, StudentResponse> map = new LinkedHashMap<>();
students.forEach(s -> map.computeIfAbsent(
s.getCourse(),
k -> new StudentResponse(s.getCourse()))
.getStudents().add(s));

这假设 StudentResponse 有一个构造函数接受类(class)作为参数和学生列表的 getter,并且这个列表是可变的(即 ArrayList)以便我们可以将当前学生添加到其中。

虽然上述方法有效,但它显然违反了基本的 OO 原则,即封装。如果您对此表示满意,那么您就完成了。如果你想尊重封装,那么你可以向 StudentResponse 添加一个方法来添加一个 Student 实例:

public void addStudent(Student s) {
students.add(s);
}

然后,解决方案将变为:

Map<String, StudentResponse> map = new LinkedHashMap<>();
students.forEach(s -> map.computeIfAbsent(
s.getCourse(),
k -> new StudentResponse(s.getCourse()))
.addStudent(s));

这个解决方案显然比以前的解决方案更好,并且可以避免被严肃的代码审查者拒绝。

这两种解决方案都依赖于 Map.computeIfAbsent,它要么为所提供的类(class)返回一个 StudentResponse(如果 map 中存在该类(class)的条目),要么创建并返回以类(class)作为参数构建的 StudentResponse 实例。然后,该学生被添加到返回的 StudentResponse 的内部学生列表中。

最后,您的 StudentResponse 实例在映射值中:

Collection<StudentResponse> result = map.values();

如果您需要一个 List 而不是 Collection:

List<StudentResponse> result = new ArrayList<>(map.values());

注意:我使用 LinkedHashMap 而不是 HashMap 来保留插入顺序,即原始列表中学生的顺序。如果你没有这样的需求,就使用HashMap

关于java - 在 java 中的 Collectors.groupingBy 之后展平 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53548602/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com