我有一个学校名单,其中包括班级,班级名单,也包括学生和学生也是另一个名单。我想要应用两个嵌套过滤器,第一个是检查任何一个班级是否有一个空的学生列表,第二个过滤器用于检查学校是否有空的类列表,最后它应该返回列表,但是我不能将两个过滤器作为嵌套,我一直会得到语法错误。我对流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());
发布于 2022-01-24 13:24:24
您可能需要添加生成的语法错误。但是,正如我首先看到的,您使用class
作为标识符,而实际上它是Java语言中的保留关键字。考虑将标识符重命名为类似的schoolClass
。
发布于 2022-01-24 14:47:44
我不确定我是否正确地理解了你,但据我所知,你想让所有的学校要么是空班,要么是没有学生的学校。
您可以做的是定义流之外的谓词。
Predicate<School> empty_students_filter = school ->
school.getSchoolClassList().stream().map(SchoolClass::getStudentList).anyMatch(List::isEmpty);
Predicate<School> empty_classes_filter = school -> school.getSchoolClassList().isEmpty();
然后可以在filter方法中使用谓词,并将它们与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:从不包含学生的学校中删除所有课程。
第二步:收集所有有课程的学校。
//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());
https://stackoverflow.com/questions/70834536
复制相似问题