一種方法是按類來分組,其中包含要分組的所有字段。這個類必須實現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