一种方法是按类来分组,其中包含要分组的所有字段。这个类必须实现hashCode
和equals
使用所有这些字段才能按预期工作。
在您的例子,这将是:
public class SubjectAndSemester {
private final String subject;
private final int semester; // an enum sounds better
public SubjectAndSemester(String subject, int semester) {
this.subject = subject;
this.semester = semester;
}
// TODO getters and setters, hashCode and equals using both fields
}
然后,你应该在你Student
类创建这种方法:
public SubjectAndSemester bySubjectAndSemester() {
return new SubjectAndSemester(subject, semester);
}
现在,你可以组分别如下:
Map<SubjectAndSemester, List<Student>> studlistGrouped = studlist.stream()
.collect(Collectors.groupingBy(Student::bySubjectAndSemester));
这创建了一个一级学生组。
有,不需要你使用Tuple
或创建一个新的类组的另一种选择。我的意思是,你可以让学生的ň -level分组,利用下游groupingBy
收藏家:
Map<String, Map<Integer, List<Student>>> studlistGrouped = studlist.stream()
.collect(Collectors.groupingBy(Student::getSubject,
Collectors.groupingBy(Student::getSemester)));
这将创建一个2级分组,所以现在返回的结构图的列表的地图。如果你能忍受这一点,即使对更多层次进行分组,也可以避免创建一个充当地图关键字的类。
非常感谢您的回答。你的答案看起来不错,但我的问题是我在这里简化了我的例子。基于用户选择,我不应该按组或应该由多达8个变量组成。在您的第一个解决方案中,我应该为每种可能性创建数千种不同的组合。 – drJava
@drJava不一定......你可以用你最需要细化的场景中的8个领域创建一个班级。然后,如果用户没有选择要分组的8个字段,只需将未选择的字段设置为null,并使得hashCode和equals就像这些空字段不存在一样,即“hashCode”对于一个空字段应该是0.而对于'equals'只是比较'null'。 Eclipse和IntelliJ会自动为您执行此操作。 –
这意味着,我需要在您的示例中只创建一个像bySubjectAndSemester这样的方法,并且不应将其分组的字段应该设置为null,其余部分与您在评论中写入的内容类似。 – drJava