我有一个元素列表,我需要按此列表类型的某些元素分组并将其转换为嵌套集合。这是我的意思-
考虑以下-
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具有“主题”列表作为元素。
这是我的想法,但没有被说服,
原始列表并构造我需要的
流api,其中groupby收集的数据看起来很有希望,
但我似乎无法将列表中的StudentA类型转换为我的
StudentB类型
什么是执行此操作的好方法?非常感谢 !
最佳答案
如果按名称对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
,并且仅在该Subject
中尚未包含所需的主题ID的情况下,才创建新的Map
,则可以避免这种情况。