将Java中的平面列表元素转换为嵌套集合

4
我是一位有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我有一个元素列表,我需要按照此列表类型的某些元素进行分组,并将其转换为嵌套集合。这就是我的意思 -

考虑以下内容 -

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列表作为元素。
这是我考虑的方式,但并不确定:
1. 传统的迭代方式,遍历原始列表中的每个元素并构造所需内容。 2. 我还查看了Java8流API,其中对收集的数据进行分组,看起来很有前途,但我似乎无法将列表中的StudentA类型转换为我的StudentB类型。
如何以高效的方式执行此操作?非常感谢!
1个回答

4
如果您按名称对 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实例。如果您创建一个Map<Integer, Subject>,其中包含按其ID索引的Subject,并且仅在该Map中不存在所需的主题ID时才创建新的Subject,则可以避免这种情况。

谢谢!这正是我所寻找的。关于创建多个相同主题实例的问题,那样做是可以的。我这里不涉及太多主题。 - ranjith
精彩的例子! - HopeKing

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