提问人:ccznyo 提问时间:1/24/2022 最后编辑:ccznyo 更新时间:1/26/2022 访问量:109
过滤 Java 嵌套列表
Filtering Java Nested List
问:
我有一个包含班级的学校列表,班级列表也包含学生,学生也是另一个列表。我想应用两个嵌套过滤器,第一个过滤器将检查是否有任何班级有一个空的学生列表,第二个过滤器用于检查学校是否有任何空的班级列表,最后它应该返回列表,但我无法应用两个嵌套过滤器,我不断收到语法错误。我对流 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());
答:
1赞
edean
1/24/2022
#1
您可能需要添加生成的语法错误。但是,正如我最初看到的,您正在用作标识符,而它实际上是 Java 编程语言中的保留关键字。考虑将标识符重命名为类似的东西。class
schoolClass
评论
0赞
ccznyo
1/24/2022
举个例子,首先 anyMatch 方法说无法解析 student 类型中的 getStudentList() 方法。我以示例代码为例,这个任务是我实习的公司交给我的
0赞
motaa
1/24/2022
#2
我不确定我是否正确理解了你,但据我所知,你想让所有有空课或没有学生课的学校都得到。
您可以做的是在流之外定义谓词。
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: 从没有学生的学校中删除所有班级。
步骤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());
评论
0赞
ccznyo
1/25/2022
谢谢你的回答,但在第一个中,我想过滤类数组,但它仍然根据类过滤学校数组,所以结果不是我真正想要的
0赞
ccznyo
1/25/2022
这里的问题是,如果学校有 3 个班级,其中一个班级没有任何学生,它会立即从列表中删除学校,但其他 2 个班级有学生,所以我不想失去他们。这就是为什么过滤应该应用于班级而不是学校,就像没有班级就没有学生一样。但我找不到如何:(
0赞
motaa
1/25/2022
我会在大约一个小时后回复你:)
评论
.filter(cls-> cls.getStudentList().size() > 0)