Java 流 - 基于子项目的过滤器

Java stream - filter based on child item

我有 List of each Person 有 List of 。手机有品牌名称和型号。如何使用 Java 流来过滤 modelNumber 等于某个值的 Person 列表。在下面的代码中,我需要过滤 persons 其 modelNumber 是 10

public static void main(String[] args) {
        
        Integer searchModel = 10;
        
        List<Person> persons = new ArrayList<>();
        CellPhone a1 = new CellPhone("Nokia", 10);
        CellPhone a11 = new CellPhone("Sony", 11);
        List<CellPhone> phoneList = new ArrayList<>();
        phoneList.add(a11);
        phoneList.add(a1);
        Person p1 = new Person("John", phoneList);
        
        CellPhone a2 = new CellPhone("Nokia", 10);
        CellPhone a22 = new CellPhone("Sony", 11);
        phoneList = new ArrayList<>();
        phoneList.add(a2);
        phoneList.add(a22);
        Person p2 = new Person("Doe", phoneList);
        
        CellPhone a3 = new CellPhone("Apple", 20);
        CellPhone a33 = new CellPhone("Samsung", 22);
        phoneList = new ArrayList<>();
        phoneList.add(a3);
        phoneList.add(a33);
        Person p3 = new Person("Rose", phoneList);
        
        CellPhone a4 = new CellPhone("Nokia", 10);
        CellPhone a44 = new CellPhone("Sony", 11);
        phoneList = new ArrayList<>();
        phoneList.add(a4);
        phoneList.add(a44);
        Person p4 = new Person("Kumar", phoneList);
        
        CellPhone a5 = new CellPhone("Apple", 20);
        CellPhone a55 = new CellPhone("Samsung", 22);
        phoneList = new ArrayList<>();
        phoneList.add(a5);
        phoneList.add(a55);
        Person p5 = new Person("Angel", phoneList);
        
        CellPhone a6 = new CellPhone("Apple", 20);
        CellPhone a66 = new CellPhone("Samsung", 22);
        phoneList = new ArrayList<>();
        phoneList.add(a6);
        phoneList.add(a66);
        Person p6 = new Person("Prince", phoneList);
        
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);
        persons.add(p5);
        persons.add(p6);
        
        
        persons.stream().filter(p -> p.getPhones().stream().filter(x -> x.getModelNumber().equals(searchModel)).collect(Collectors.toList()));
    
    // expected Person list is John, Doe and Kumar
    // above filter gives me an error cannot convert from list to boolean
    }

您可以为您的人物添加一个 hasPhone 函数 class:

public boolean hasPhone(int modelNumber) {
     return phones.stream()
                 .anyMatch(phone -> phone.getModelNumber() == modelNumber);
}

现在只需按如下方式过滤您的人员列表:

List<Person> result = persons.stream()
                .filter(person -> person.hasPhone(10))
                .collect(Collectors.toList());

请注意 .filter(x -> x.getModelNumber().equals(searchModel)).collect(Collectors.toList()) 做 return 一个 phone 的列表而不是布尔值。您要问的是“那个人的 phone 的哪个模型编号为 10?”当您真正想知道“这个人是否拥有型号为 10 的 phone?”时。询问某人是否拥有具有特定型号的 phone 的概念很好地绑定到该人本身,因此应包含在 Person class.

.filter 期望 Predicate 而您的代码在外部 .filter.

中没有这个

您可以这样做:

persons.stream()
    .filter(p -> p.getPhones().stream()
                    .anyMatch(x -> x.getModelNumber() == searchModel)
    ).collect(Collectors.toList()));

注意如果getModelNumber()的return类型是int,则需要使用==而不是.equals