1. 概述

在本教程中,我们将深入探讨 Java 8 中 Stream.count() 方法的使用。重点在于如何将 count()filter() 方法结合,来统计满足某个 Predicate 条件的元素数量。

2. 使用 Stream.count()

count() 方法虽然功能简单,但非常实用。它常与其他 Stream 操作配合使用,尤其是 filter() 方法。

我们继续沿用在 Stream.filter() 教程 中定义的 Customer 类:

public class Customer {
    private String name;
    private int points;
    // 构造函数和标准 getter 方法
}

并创建一组客户数据:

Customer john = new Customer("John P.", 15);
Customer sarah = new Customer("Sarah M.", 200);
Customer charles = new Customer("Charles B.", 150);
Customer mary = new Customer("Mary T.", 1);

List<Customer> customers = Arrays.asList(john, sarah, charah, mary);

接下来,我们将在该集合上使用 Stream 方法进行过滤并统计匹配项的数量。

2.1. 统计元素总数

先看 count() 最基础的用法:

long count = customers.stream().count();

assertThat(count).isEqualTo(4L);

⚠️ 注意:count() 返回的是 long 类型,不是 int

2.2. 将 count()filter() 结合使用

前面的例子其实没啥技术含量,直接用 List.size() 也能得到相同结果。

Stream.count() 的真正价值在于与其他流操作组合使用,最常见的就是配合 filter()

long countBigCustomers = customers
  .stream()
  .filter(c -> c.getPoints() > 100)
  .count();

assertThat(countBigCustomers).isEqualTo(2L);

在这个例子中,我们过滤出积分超过 100 的客户,并统计数量。结果是 2 个符合条件的客户。

当然,也可能一个都不匹配:

long count = customers
  .stream()
  .filter(c -> c.getPoints() > 500)
  .count();

assertThat(count).isEqualTo(0L);

2.3. 使用复杂条件进行过滤统计

filter() 教程中我们介绍过一些更高级的用法,这些场景下同样可以使用 count() 来统计结果。

✅ 多条件过滤:

long count = customers
  .stream()
  .filter(c -> c.getPoints() > 10 && c.getName().startsWith("Charles"))
  .count();

assertThat(count).isEqualTo(1L);

这段代码统计了名字以 “Charles” 开头 积分大于 10 的客户数量。

✅ 使用方法引用:

long count = customers
  .stream()
  .filter(Customer::hasOverHundredPoints)
  .count();

assertThat(count).isEqualTo(2L);

这里我们将判断逻辑封装在 Customer 类的方法中,然后通过方法引用进行过滤统计,代码更清晰、复用性更强。

3. 小结

本文通过多个示例展示了如何将 count()filter() 组合使用来处理流数据。如果你还想了解 count() 的更多用法,可以看看我们关于 concat() 合并流 的教程,里面也展示了其他返回 Stream 的方法。

一如既往,完整代码可以在 GitHub 上找到。


原始标题:Counting Matches on a Stream Filter