filter()详解2

1. 对象集合 filter() 示例

我们以一个 Person 类为例来详细说明如何在对象集合中使用 filter()

Person 类定义:
class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

Person 类有两个属性:nameage。我们可以创建一个 Person 对象的集合(如 List<Person>),并使用 filter() 对这些对象进行筛选。

创建 Person 对象集合:
List<Person> people = Arrays.asList(
    new Person("Alice", 22),
    new Person("Bob", 17),
    new Person("Charlie", 20),
    new Person("David", 15),
    new Person("Eva", 25)
);

在这个示例中,people 是一个包含 5 个 Person 对象的列表。

2. 根据对象的属性筛选

现在,假设我们想从这个列表中筛选出所有年龄大于 18 的成年人。这时候我们可以使用 filter() 方法,传递一个基于 Person 对象属性的条件。

筛选成年人(年龄大于 18):
List<Person> adults = people.stream()
    .filter(person -> person.age > 18)  // 筛选出年龄大于 18 的人
    .collect(Collectors.toList());      // 将结果收集到一个 List 中

System.out.println(adults);

输出结果:

[Alice (22), Charlie (20), Eva (25)]

解释

  • people.stream():将 people 集合转化为流。
  • filter(person -> person.age > 18):传递一个 Predicate 表达式,这里我们检查 person.age > 18,即筛选出年龄大于 18 的人。
  • collect(Collectors.toList()):将满足条件的 Person 对象收集到一个新的 List<Person> 中。

3. 组合多个筛选条件

有时候,你可能需要根据多个属性进行筛选,比如年龄大于 18 且名字以字母 ‘A’ 开头的对象。可以通过在 filter() 中组合条件来实现。

筛选成年人且名字以 ‘A’ 开头:
List<Person> specificAdults = people.stream()
    .filter(person -> person.age > 18 && person.name.startsWith("A"))
    .collect(Collectors.toList());

System.out.println(specificAdults);

输出结果:

[Alice (22)]

解释

  • filter(person -> person.age > 18 && person.name.startsWith("A")):这里的筛选条件是年龄大于 18 且名字以 ‘A’ 开头,这两个条件通过逻辑 && 连接。

4. 使用多个 filter()

你也可以使用多个 filter() 方法分别定义不同的条件。最终的效果是对流中元素逐层过滤。

使用多个 filter() 进行筛选:
List<Person> adults = people.stream()
    .filter(person -> person.age > 18)      // 首先筛选出年龄大于 18 的人
    .filter(person -> person.name.startsWith("C"))  // 然后筛选名字以 'C' 开头的人
    .collect(Collectors.toList());

System.out.println(adults);

输出结果:

[Charlie (20)]

解释

  • 第一个 filter(person -> person.age > 18) 筛选出所有成年人。
  • 第二个 filter(person -> person.name.startsWith("C")) 在成年人中进一步筛选名字以 ‘C’ 开头的人。

这种写法的好处是每个 filter() 都处理一个简单条件,逻辑清晰,代码也更具可读性。

5. 复杂对象的筛选

如果对象属性较为复杂,比如有嵌套对象、列表或者对象的其他对象属性,也可以用 filter() 对这些嵌套属性进行筛选。假设我们扩展 Person 类,添加一个 address 属性,并且 Address 类包含 citycountry 字段:

扩展的 PersonAddress 类:
class Address {
    String city;
    String country;

    Address(String city, String country) {
        this.city = city;
        this.country = country;
    }
}

class Person {
    String name;
    int age;
    Address address;

    Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    public String toString() {
        return name + " (" + age + ") - " + address.city + ", " + address.country;
    }
}

在这个结构中,每个 Person 对象有一个 Address 对象,Address 包含城市和国家的相关信息。

创建对象集合:
List<Person> people = Arrays.asList(
    new Person("Alice", 22, new Address("New York", "USA")),
    new Person("Bob", 17, new Address("London", "UK")),
    new Person("Charlie", 20, new Address("San Francisco", "USA")),
    new Person("David", 15, new Address("Paris", "France")),
    new Person("Eva", 25, new Address("Berlin", "Germany"))
);
根据 Address 属性进行筛选

假设我们希望筛选出所有居住在美国 (USA) 的人,使用 filter() 访问 Address 属性进行筛选:

List<Person> peopleInUSA = people.stream()
    .filter(person -> "USA".equals(person.address.country))  // 筛选居住在 USA 的人
    .collect(Collectors.toList());

System.out.println(peopleInUSA);

输出结果:

[Alice (22) - New York, USA, Charlie (20) - San Francisco, USA]

解释

  • filter(person -> "USA".equals(person.address.country)):我们通过访问 Person 对象的 address 属性,再检查 country 字段是否等于 “USA”,来筛选居住在美国的所有人。

6. 流式编程的强大之处

通过 filter(),我们可以灵活地根据对象的各种属性(甚至是嵌套属性)来筛选复杂的数据结构。这种流式编程风格不仅简化了代码,还使代码更具可读性和可维护性。

总结

  • filter() 可以用来根据对象属性对对象集合进行筛选。
  • 可以组合多个条件、链式调用多个 filter() 进行复杂的筛选。
  • 可以对对象的嵌套属性进行过滤。
  • 这种方式能简化处理复杂集合的代码逻辑,同时提高代码的可读性和灵活性。

reduce()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值