如何避免Java代码中的java.util.ConcurrentModificationException异常?
解决HashMap遍历删除时的ConcurrentModificationException问题
你现在的问题出在第二个for-each循环里——遍历keySet的同时调用students.remove(key)修改了原HashMap,触发了Java的快速失败机制,所以抛出了ConcurrentModificationException。给你两个简便的解决办法:
方法一:循环直到Map为空(需要修改原Map时用)
不用在遍历keySet的过程中删除元素,直接循环判断Map是否为空,每次找到当前最高分的键值对后删除并输出:
// 计算、格式化并输出分数 public static void sort(final HashMap<String, Integer> students) { // 先输出原Map内容 for (String i : students.keySet()) { System.out.println("key: " + i + " value: " + students.get(i)); } // 循环直到Map中无元素 while (!students.isEmpty()) { // 获取当前成绩最高的学生的键 String key = Collections.max(students.entrySet(), Map.Entry.comparingByValue()).getKey(); System.out.println(key + " " + students.get(key)); // 删除该键值对 students.remove(key); } }
这种方式避开了遍历过程中修改Map的操作,自然不会触发异常。
方法二:先排序再输出(更高效,不修改原Map)
你的核心需求是按成绩从高到低输出,完全没必要删除原Map里的元素。直接把Map的entrySet转成列表排序后输出,效率更高(时间复杂度从O(n²)降到O(nlogn)),还能保留原Map的内容:
// 计算、格式化并输出分数 public static void sort(final HashMap<String, Integer> students) { // 先输出原Map内容 for (String i : students.keySet()) { System.out.println("key: " + i + " value: " + students.get(i)); } // 将键值对转成列表,按成绩降序排序 List<Map.Entry<String, Integer>> sortedStudents = new ArrayList<>(students.entrySet()); sortedStudents.sort(Map.Entry.comparingByValue(Comparator.reverseOrder())); // 遍历输出排序后的结果 for (Map.Entry<String, Integer> entry : sortedStudents) { System.out.println(entry.getKey() + " " + entry.getValue()); } }
这个方法既解决了异常问题,又更符合业务逻辑的最优实现,更推荐使用。
内容的提问来源于stack exchange,提问作者Bryson Noble
相关产品推荐
相关产品推荐

