商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Java 中数组怎么高效统计每个元素的频率

Java 中数组怎么高效统计每个元素的频率

  发布于2026-07-07 阅读(0)

扫一扫,手机访问

说到统计Ja va数组元素频率,很多人第一反应就是双重循环暴力计数——但那样效率太低了。实际上,有几种高效方案:HashMap手动遍历(O(n),通用清晰)、IntStream + groupingBy(适合基本类型,有装箱开销),或者计数数组(非负整数且范围有限时性能直接拉满)。记住一条铁律:避免嵌套循环、重复流操作,那是给自己挖坑。

Ja va 中数组怎么高效统计每个元素的频率

那么具体怎么选?核心原则很简单:时间复杂度控制在 O(n),同时兼顾可读性和内存开销。下面逐一拆解。

用 HashMap 手动遍历(通用、清晰、推荐)

这个方法适用于任意类型数组,包括自定义对象(前提是保证 equals()hashCode() 正确实现)。遍历一次,边读边累加:

  • 创建 Map,键为元素,值为出现次数。
  • 对每个元素:用 map.merge(element, 1, Integer::sum) 最简洁;或用 getOrDefaultput 也行。
  • 整型数组示例: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 流:

  • Map freq = 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():内存占用高,还没发挥哈希查找的优势。
本文转载于:https://www.php.cn/faq/2780342.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注