筛选Java嵌套列表



我有一个学校列表,其中包含class,class列表也包含student,student也是另一个列表。我想应用两个嵌套的过滤器,第一个过滤器将检查是否有任何班级有空的学生列表,第二个过滤器用于检查学校是否有空的班级列表,最后它应该返回列表,但我不能将两个过滤器应用为嵌套的,我不断出现语法错误。我对流式api有点陌生。

result = result.stream()
.filter(school -> school.getSchoolClassList().stream()
.filter(schoolClass-> schoolClass.getStudentList().stream()
.anyMatch(schoolClass-> schoolClass.getStudentList().size() > 0))
.anyMatch(school -> school.getSchoolClassList().size() > 0))
.collect(Collectors.toList());

您可能需要添加由此产生的语法错误。然而,正如我最初看到的,您使用class作为标识符,而它实际上是Java编程语言中的一个保留关键字。考虑将标识符重命名为类似的schoolClass

我不确定我是否正确理解你,但据我所知,你想让所有的学校要么有空课,要么有没有学生的课。

您可以做的是在流之外定义谓词。

Predicate<School> empty_students_filter = school ->
school.getSchoolClassList().stream().map(SchoolClass::getStudentList).anyMatch(List::isEmpty);
Predicate<School> empty_classes_filter = school -> school.getSchoolClassList().isEmpty();

然后,您可以在筛选方法中使用谓词,并将它们与Predicate.or((:组合

List<School> schools_with_no_or_empty_classes = 
schools.stream()
.filter(empty_classes_filter.or(empty_students_filter))
.collect(Collectors.toList());

注意:如果你只想得到有课的学校,而所有的课都应该有学生,那么你可以用Predicate.and((调整过滤器,如下所示:

.filter(Predicate.not(empty_classes_filter).and(Predicate.not(empty_students_filter)))

编辑:

根据您的评论,使用Streams API不容易做到这一点,因为您在学校集合上迭代,并且只能根据学校的属性过滤学校,而不能过滤学校的属性。因此,您需要实现自己的自定义收集器。

我建议分两步解决这个问题。

步骤1:从没有学生的学校中删除所有班级。

第2步:流式传输并收集所有有课的学校。

//step 1:
result.forEach(school -> {
List<SchoolClass> school_classes = school.getSchoolClassList();
List<SchoolClass> empty_classes = 
school_classes.stream()
.filter(school_class -> school_class.getStudentList().isEmpty())
.collect(Collectors.toList());
school.getSchoolClassList().removAll(empty_classes);
});
//step 2:
List<School> remaining_schools = result.stream()
.filter(school -> !school.getSchoolClassList().isEmpty())
.collect(Collectors.toList());

最新更新