0

我有一个包含班级的学校列表,也包含学生和学生的班级列表也是另一个列表。我想应用两个嵌套过滤器,首先检查是否有任何班级有一个空的学生列表,第二个过滤器用于检查学校是否有任何空班级列表,最后它应该返回列表,但我不能应用两个过滤器嵌套时,我不断收到语法错误。我对流 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());
4

2 回答 2

1

您可能想要添加生成的语法错误。class但是,正如我首先看到的那样,当它实际上是 Java 编程语言中的保留关键字时,您将其用作标识符。考虑将标识符重命名为 alike schoolClass

于 2022-01-24T13:24:24.163 回答
0

我不确定我是否正确理解了您,但据我所知,您希望获得所有有空班或没有学生的班级的学校。

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

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());
于 2022-01-24T14:47:44.530 回答