Java 中数组怎么高效统计每个元素的频率
作者:水悠悠予安
时间:2026-07-07
浏览:0
统计数组元素频率可采用HashMap手动遍历(O(n),通用清晰)、IntStream+groupingBy(函数式但有装箱开销)或计数数组(非负整数且范围有限时性能最优)。避免嵌套循环和重复流操作,优先保证线性时间复杂度和可读性。
说到统计Ja va数组元素频率,很多人第一反应就是双重循环暴力计数——但那样效率太低了。实际上,有几种高效方案:HashMap手动遍历(O(n),通用清晰)、IntStream + groupingBy(适合基本类型,有装箱开销),或者计数数组(非负整数且范围有限时性能直接拉满)。记住一条铁律:避免嵌套循环、重复流操作,那是给自己挖坑。

那么具体怎么选?核心原则很简单:时间复杂度控制在 O(n),同时兼顾可读性和内存开销。下面逐一拆解。
用 HashMap 手动遍历(通用、清晰、推荐)
这个方法适用于任意类型数组,包括自定义对象(前提是保证 equals() 和 hashCode() 正确实现)。遍历一次,边读边累加:
- 创建
Map,键为元素,值为出现次数。 - 对每个元素:用
map.merge(element, 1, Integer::sum)最简洁;或用getOrDefault再put也行。 - 整型数组示例:
int[] arr = {1,2,2,3,3,3};→Map,循环中freq = new HashMap<>(); freq.merge(x, 1, Integer::sum);一步到位。
用 IntStream + groupingBy(仅限 int/long/double,函数式风格)
如果你偏爱函数式写法,可以用 Stream 来实现。但注意隐含的装箱开销:Arrays.stream(arr) 对 int[] 返回的是 IntStream,必须调用 .boxed() 才能转为 Integer 流:
Mapfreq = Arrays.stream(arr).boxed().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); - 返回值是
Long计数,如果你非要Integer,可以换成Collectors.summingInt(e -> 1)。 - 小数据量代码确实紧凑,但大数组频繁装箱会影响性能,权衡着用。
针对纯正整数且范围有限的场景:用计数数组(最快,O(1) 查找)
当元素都是非负整数,且最大值已知且不太大(比如 0~10000),直接用数组索引当键:
- 申请
int[] count = new int[maxValue + 1]; - 遍历原数组:对每个
x,执行count[x]++。 - 不需要哈希计算,没有装箱,内存局部性好——速度最快。
- 缺点也明显:不支持负数、字符串、大范围或稀疏数据(比如元素是 1 和 999999,浪费大量空间)。
避免常见低效写法
以下写法尽量避开:
- 双重 for 循环逐个统计:时间复杂度 O(n²),数据量一上万就肉眼可见地慢。
- 每次调用
Arrays.asList(arr).stream().filter(...).count():反复创建流和中间集合,开销巨大。 - 用 ArrayList 存所有相同元素再取 size():内存占用高,还没发挥哈希查找的优势。
作者最新文章
灵活计算器
2026-09-16 17:45
苹果折叠屏iPhone预计售价是多少
2026-09-14 13:44
OpenAI GPT-6 Astra 自主通关《传送门》:技术原理与实验成本解析
2026-09-08 19:08
苹果与铠侠签署NAND长期供应协议:3-5年长约与不设价格上限背后的供应链战略
2026-09-08 16:58
PDF转PPT操作指南:在线、本地与批量转换及结果核对
2026-09-04 15:04
热门文章
更多
精品专题
更多
Mac软件
更多
WINDOWS
更多


































