我有一个元素列表,我需要按此列表类型的某些元素进行分组,并将其转换为嵌套集合。这就是我的意思 -
请考虑以下内容 -
class StudentA {
private String name;
private int age;
private int subjectId;
private String subjectName;
}
class StudentB {
private String name;
private int age;
List<Subject> subject;
}
class Subject {
private int subjectId;
private String subjectName;
}
我有List<StudentA>
作为我的输入。但是在这个列表中,每个学生可以有多个科目,因此学生信息是重复的(例如:[new StudentA("A",22,1,"X"), new StudentA("A",22,2,"Y"), new StudentA("B",24,1,"X") ]
等等)。
这不是一个好的表示,我需要以下格式的数据 -
List<StudentB>
请注意,StudentB将Subject列为元素。
这是我的想法,但不相信,
执行此操作的有效方法是什么?非常感谢!
答案 0 :(得分:3)
如果您按名称对StudentA
的实例进行分组,则会获得Map<String,List<StudentA>>
。然后,您可以流式传输此地图的值并将其转换为StudentB
的实例:
List<StudentB> bList =
aList.stream() // Stream<StudentA>
.collect(Collectors.groupingBy(StudentA::getName)) // Map<String,List<StudentA>>
.values() // Collection<List<StudentA>>
.stream() // Stream<List<StudentA>>
.map(list -> {
StudentB b = new StudentB();
b.setName(list.get(0).getName());
b.setAge(list.get(0).getAge());
list.forEach(a -> b.addSubject(new Subject(a.getSubjectID(),a.getSubjectName())));
return b;
}) // Stream<StudentB>
.collect(Collectors.toList());
我冒昧地假设存在一些方法名称和构造函数。
此解决方案的缺点是可能为同一Subject
创建多个Subject
个实例。如果您创建的Map<Integer,Subject>
包含由其ID标记的Subject
,并且只有在{{1}中尚未包含所需主题ID的情况下才创建新Subject
,则可以避免这种情况}}