Java删除联系人时触发ConcurrentModificationException异常求助
解决Java ConcurrentModificationException异常(删除联系人场景)
异常原因
增强for循环(for (Contact c: contacts))底层依赖集合的迭代器实现。当你在遍历过程中直接调用contacts.remove(c)修改集合结构时,迭代器内部的修改次数计数器和集合的实际修改次数会出现不一致,触发迭代器的fail-fast检查机制,从而抛出ConcurrentModificationException。
解决方案1:使用迭代器的remove方法
直接通过集合的迭代器遍历,调用迭代器自身的remove()方法,这样迭代器会同步更新内部的修改次数,不会触发异常:
private static void deleteContact() { System.out.println("Please enter the name:"); String name = scanner.next(); if (name.equals("")) { System.out.println("!Please enter the name"); deleteContact(); } else { boolean doesExist = false; Iterator<Contact> iterator = contacts.iterator(); while (iterator.hasNext()) { Contact c = iterator.next(); if (c.getName().equals(name)) { doesExist = true; iterator.remove(); // 使用迭代器自带的remove方法 } } if (!doesExist) { System.out.println("There is no such contact"); } } showInitialOptions(); }
解决方案2:使用倒序普通for循环
通过索引遍历集合,采用倒序方式可以避免删除元素后索引错乱的问题:
private static void deleteContact() { System.out.println("Please enter the name:"); String name = scanner.next(); if (name.equals("")) { System.out.println("!Please enter the name"); deleteContact(); } else { boolean doesExist = false; // 倒序遍历,删除元素后不会影响后续元素的索引位置 for (int i = contacts.size() - 1; i >= 0; i--) { Contact c = contacts.get(i); if (c.getName().equals(name)) { doesExist = true; contacts.remove(i); } } if (!doesExist) { System.out.println("There is no such contact"); } } showInitialOptions(); }
解决方案3:使用Java 8+流式API过滤
通过流式API过滤掉需要删除的元素,生成新集合替换原集合(如果允许修改原集合引用):
import java.util.stream.Collectors; private static void deleteContact() { System.out.println("Please enter the name:"); String name = scanner.next(); if (name.equals("")) { System.out.println("!Please enter the name"); deleteContact(); } else { // 过滤掉目标联系人,生成新集合 List<Contact> filteredContacts = contacts.stream() .filter(c -> !c.getName().equals(name)) .collect(Collectors.toList()); // 通过集合大小变化判断是否存在目标联系人 boolean doesExist = contacts.size() != filteredContacts.size(); contacts = filteredContacts; // 替换原集合 if (!doesExist) { System.out.println("There is no such contact"); } } showInitialOptions(); }
注意:如果contacts被final修饰无法直接替换引用,可以改为先清空原集合,再添加过滤后的元素:
contacts.clear(); contacts.addAll(filteredContacts);
内容的提问来源于stack exchange,提问作者Mr. Zahangir Alam Joy
相关产品推荐
相关产品推荐

