如何修正Java方法以输出数组中出现次数最多的前5个数字?
问题分析与解决方案
问题根源
你的top5方法错误地将哈希表的键和值分开存储并单独排序:哈希表的keySet()和values()本身是无序的,单独对values列表降序排序后,keys列表的顺序并未同步调整,导致输出的数字(键)和对应的出现次数(值)完全不匹配。
修正后的完整代码
我们需要将键值对作为整体排序,确保排序后数字和次数始终对应。以下是修正后的完整代码:
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Random; public class HW4 { public static void main(String[] args) { int[] a = getRandom(20, 1, 10); System.out.println(Arrays.toString(a)); System.out.println(); occurrence(a); System.out.println(); top5(a); } public static int[] getRandom(int n, int low, int high) { long seed = 0; Random random = new Random(seed); random.setSeed(seed); int[] result = new int[n]; for (int i = 0; i < n; i++) { result[i] = random.nextInt(high - low) + low; } return result; } public static void occurrence(int[] x) { HashMap<Integer, Integer> occurrences = new HashMap<>(); for (int key : x) { occurrences.put(key, occurrences.getOrDefault(key, 0) + 1); } for (int key : occurrences.keySet()) { System.out.println(key + " occurs: " + occurrences.get(key) + " times"); } } public static void top5(int[] arr) { // 1. 统计元素出现次数(用getOrDefault简化代码) HashMap<Integer, Integer> lookup = new HashMap<>(); for (int key : arr) { lookup.put(key, lookup.getOrDefault(key, 0) + 1); } // 2. 将哈希表的键值对转换为列表,作为整体处理 ArrayList<Map.Entry<Integer, Integer>> entryList = new ArrayList<>(lookup.entrySet()); // 3. 自定义排序规则:按出现次数降序;次数相同时按数字升序(保证结果一致性) Collections.sort(entryList, (entry1, entry2) -> { int countCompare = entry2.getValue().compareTo(entry1.getValue()); if (countCompare == 0) { return entry1.getKey().compareTo(entry2.getKey()); } return countCompare; }); // 4. 输出前5个元素(如果元素总数不足5个,输出全部) int displayCount = Math.min(5, entryList.size()); for (int i = 0; i < displayCount; i++) { Map.Entry<Integer, Integer> entry = entryList.get(i); System.out.println(entry.getKey() + " occurs: " + entry.getValue() + " times"); } } }
关键修正点
- 键值对整体处理:使用
Map.Entry将数字和对应的出现次数绑定,排序时不会断开关联。 - 自定义排序逻辑:优先按出现次数降序排列,次数相同时按数字本身升序,避免相同次数的数字顺序随机。
- 边界处理:用
Math.min(5, entryList.size())处理数组元素种类不足5个的情况,避免索引越界。 - 代码简化:用
getOrDefault替代containsKey判断,简化统计次数的代码。
测试结果
对于示例数组[7, 8, 5, 3, 9, 3, 9, 4, 7, 3, 6, 9, 3, 2, 9, 6, 5, 7, 6, 3],修正后的top5方法会输出期望结果:
3 occurs: 5 times 9 occurs: 4 times 6 occurs: 3 times 7 occurs: 3 times 5 occurs: 2 times
内容的提问来源于stack exchange,提问作者Ezequiel Soler Perez
相关产品推荐
相关产品推荐

