簡體   English   中英

使用 Java Streams 過濾嵌套列表

[英]Filtering of nested lists with Java Streams

我需要過濾一些嵌套列表。 考慮一個包含List<B>List<A> ,其中包含List<C> 我需要過濾,返回包含至少一個滿足給定條件的 B 和至少一個滿足給定條件的 C 的所有 A 對象。

我在下面有一個人為的例子,它基本上是在做我在我的實際例子中試圖實現的事情。 拿一個城市的學校列表,每個學校有很多學科,每個學科有很多老師。 我想保留一份包含 subject.subjectName = 'Math' 的學校列表,並且該科目中至少有一名教師 teacher.age > 65。

我已經使用自定義謂詞實現了這個,所以我也在我的示例中做了一個 this 。 我收到“無法從 boolean 轉換為 Stream”的錯誤,但老實說,我在這種情況下很掙扎。

    @Getter
    @Setter
    class School {
        private String schoolId;
        private List<Subject> classes;
        
    }
        
    @Getter
    @Setter
    class Subject {
        String subjectName;
        List<Teacher> teachers;
    }
    
    @Getter
    @Setter
    class Teacher {
        private String teacherName;
        private Integer age;
    }

    public class TestClass {
        public static void main( String[] args ){
            List<School> schools;
            
            // Get All schools where A mathTeacher is over retirement age
            List<School> schoolsWithRetirementAgeMathTeachers = schools.stream()
                    .filter(school -> null != school.getClasses())
                    .flatMap(school -> {
                        return school.getClasses().stream()
                                .filter(subject -> subject.getSubjectName().equalsIgnoreCase("Math"))
                                .filter(subject -> null != subject.getTeachers())
                                .flatMap(subject -> {
                                    return subject.getTeachers().stream()
                                            .filter(teacher -> teacher != null)
                                            .anyMatch(isRetirementAge);
                                });
                    }).collect(Collectors.toList());
                    
        }
                
        public static Predicate<Teacher> isRetirementAge = teacher -> teacher.getAge() > 65;
    
    }

如果你試圖返回父對象,你不想使用flatMap() 您只需要嵌套一些anyMatch()調用:

List<A> filtered = listA.stream()
        .filter(a -> a.getListB()
                .stream()
                .anyMatch(b -> testB(b) && b.getListC()
                        .stream()
                        .anyMatch(c -> testC(c))))
        .collect(Collectors.toList());

由於您正在尋找School作為 output,因此您不需要將map / flatmap您的 stream 平面映射到另一個 object。 filter功能必須足夠智能,通過嵌套的anyMatch根據您的要求確認 88354248716628 .

主要在下面的代碼中,我們過濾了所有存在名稱為“數學”的科目並且其中一位教授數學的老師超過上述退休年齡的學校。

// Get All schools where a Math teacher is over retirement age
List<School> schoolsWithRetirementAgeMathTeachers = schools.stream()
        .filter(school -> school.getSubjects()
                .stream()
                .anyMatch(subject ->
                        subject.getName().equalsIgnoreCase("Math") &&
                                subject.getTeachers()
                                        .stream()
                                        .anyMatch(isRetirementAge)
                ))
        .collect(Collectors.toList());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM