collectors.counting()是java中用于统计stream元素数量的收集器,返回long类型结果,需配合collect()使用,支持空流、过滤计数及与groupingby联用实现分类统计,但不可直接调用且不处理null。

Java 中 Collectors.counting() 是一个专门用于统计 Stream 元素数量的收集器,它返回 Long 类型结果,必须配合 stream.collect() 使用,不能直接调用。
基础用法:统计全部元素个数
最简单的场景是获取流中总元素数,等价于 list.size() 或 stream.count(),但更适合嵌入收集流程:
- 写法:
stream.collect(Collectors.counting()) - 结果类型固定为
Long,即使集合很小也要注意接收变量类型匹配 - 空流安全:
Stream.empty().collect(Collectors.counting())返回0L - 示例:List
list = Arrays.asList("a", "b", "c"); long n = list.stream().collect(Collectors.counting()); // 得到 3
配合 filter 统计符合条件的元素
在计数前加入过滤逻辑,无需手动遍历,语义清晰且并行安全:
- 单条件:
words.stream().filter(w -> w.startsWith("a")).collect(Collectors.counting()) - 多条件:
numbers.stream().filter(n -> n > 5 && n % 2 == 0).collect(Collectors.counting()) - 查某元素出现次数:
list.stream().filter(e -> e.equals(target)).collect(Collectors.counting())
与 groupingBy 联合实现分类计数
这是 counting() 最典型、最有价值的使用场景——按属性或规则分组后自动统计每组数量:
- 按字符串值分组:
fruits.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) - 按对象字段分组(如 Person.city):
people.stream().collect(Collectors.groupingBy(Person::getCity, Collectors.counting())) - 按计算逻辑分组(如年龄段):
persons.stream().collect(Collectors.groupingBy(p -> p.getAge() / 10 * 10, Collectors.counting())) - 注意:下游 Map 的 value 类型必须是
Long,例如Map<string long></string>
注意事项和常见误区
看似简单,但容易踩坑:
- 不能写成
stream.counting()—— 它不是 Stream 方法,而是静态工厂方法,必须通过Collectors.counting() - 不要为单纯求总数而用它:相比
stream.count(),collect(counting())多一层 Collector 框架开销,无额外收益 - 源集合为
null会抛NullPointerException,需提前判空(counting()本身不处理 null) - 若需 int 结果,可强转:
int count = Math.toIntExact(stream.collect(Collectors.counting())),但要确保不会溢出
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











