Java数组无法直接按元素频率排序,需用HashMap统计频次,再通过List+自定义比较器或Stream API实现:先按频次降序,频次相同时可按数值升序或首次出现索引升序,结果保持原长度、不去重。

Java 中数组本身不支持直接按元素频率排序,需要借助额外的数据结构统计频次,再按频次重新组织元素。核心思路是:先统计每个元素出现次数,再按频次(主序)和原值或出现顺序(次序)排序。
用 HashMap 统计频次 + List 转换后排序
这是最常用、清晰且易理解的方式。适用于 int 数组或可哈希的元素类型。
- 遍历原数组,用 HashMap<Integer, Integer> 记录每个数的出现次数
- 将数组转为 List<Integer>,然后用 Collections.sort() 自定义比较器
- 比较逻辑:先比频次(降序),频次相同时可按数值升序(或保持原始首次出现顺序)
保持原始相对顺序(稳定排序)的技巧
如果相同频次的元素要按它们在原数组中**首次出现的先后顺序**排列,需额外记录首次索引。
- 用 LinkedHashMap 或单独的 Map<Integer, Integer> 存首次位置
- 排序时,当频次相等,比较首次出现索引(升序)
- 示例:数组 [4, 4, 2, 2, 1] → 频次均为 2 的 4 和 2,4 先出现,所以排在前面
使用 Stream API(Java 8+)简洁实现
适合函数式风格,代码更紧凑,但注意中间会生成多个对象,大数据量时略影响性能。
立即学习“Java免费学习笔记(深入)”;
- 先用 Collectors.groupingBy 统计频次
- 用 stream().sorted() 按频次降序,再用 thenComparing 处理平局
- 最后 mapToInt 转回 int[],或收集为 List
注意重复元素与原始数组长度
按频次排序后,结果数组长度不变,只是元素位置重排;不会去重,也不会改变元素个数。
- 比如 [1, 2, 2, 3, 3, 3] → 频次:1→1次,2→2次,3→3次 → 排序后可能是 [3, 3, 3, 2, 2, 1]
- 若需去重后再按频次排,需先用 distinct() 或 Set 过滤,但那就不是“数组按频率排序”而是“频次统计结果排序”了


















