Stream.count()与Collectors.counting()的区别及选型指南
Stream.count() 与 Collectors.counting() 的差异、选型及性能对比
核心差异
- 所属类与适用场景不同:
Stream.count()是Stream接口自带的终端操作方法,直接作用于流本身,调用后即可返回全量元素的计数结果;Collectors.counting()是Collectors工具类提供的收集器实现,只能作为collect()方法的入参使用,核心定位是配合分组、分区等多级收集逻辑使用。 - 返回值类型不同:
Stream.count()直接返回基础类型long;Collectors.counting()的返回值为包装类型Long,如果后续逻辑需要用到基础类型,会产生额外的自动拆箱开销。 - 优化机制不同:JDK 9及以上版本对
Stream.count()做了短路优化,如果流的数据源是可直接获取容量的集合(比如ArrayList、Array),且没有会改变元素数量的中间操作,会直接跳过遍历逻辑返回数据源的size;Collectors.counting()目前没有这类优化,所有场景下都需要遍历全量元素完成计数。
日常开发选型建议
- 单纯需要统计整个流的元素总数时,优先选
Stream.count(),代码更简洁,可读性也更高。 - 涉及分组计数、分区计数等复合收集场景时,只能选择
Collectors.counting(),示例用法如下:
// 按商品分类分组统计各分类下的商品数量 Map<String, Long> categoryCount = goodsList.stream() .collect(Collectors.groupingBy(Goods::getCategory, Collectors.counting()));
性能优劣对比
- 普通遍历场景下二者性能差距极小,核心开销都是元素遍历累加,差异可以忽略不计。
- JDK9+的可优化场景下
Stream.count()性能远超Collectors.counting():比如对100万元素的ArrayList直接做计数,stream().count()直接返回集合size,耗时为纳秒级;stream().collect(Collectors.counting())需要遍历全量元素,耗时高出几个数量级。 - 涉及基础类型操作的场景下
Stream.count()性能更优,不需要额外的拆箱操作。
内容的提问来源于stack exchange,提问作者Hiro_Hamada
相关产品推荐
相关产品推荐

