You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:25:11