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

在onPostExecute()遍历ArrayList模型触发ConcurrentModificationException问题

解决遍历ArrayList时触发ConcurrentModificationException的问题

首先,咱们先搞清楚为什么会出现这个异常:你用**增强for循环(for-each)**遍历Items的时候,直接调用Items.add()修改集合,这触发了ArrayList的「快速失败」机制。ArrayList的迭代器在遍历过程中,会检测集合是否被结构性修改(比如add/remove这类操作),如果发现就会抛出这个异常,防止并发修改导致的数据不一致。

另外,你的去重逻辑也存在问题:现在的写法会导致同一个元素被多次添加——比如当Items里已有多个元素时,只要其中一个元素的id不匹配当前id,就会执行一次add,最终同一个id可能被重复添加好几次。

下面给你几个可行的解决方案,以及修正后的去重逻辑:

方案1:用普通索引循环代替增强for循环

普通for循环不依赖迭代器,直接通过索引访问元素,所以可以安全地在循环中修改集合。同时先修正去重逻辑:先检查整个集合里是否存在目标id,不存在再添加。

JSONArray data = obj.getJSONArray("response");
for (int i = 0; i < data.length(); i++) {
    String id = data.getJSONObject(i).optString("id");
    boolean isExist = false;
    // 先检查Items中是否已存在该id
    for (int j = 0; j < Items.size(); j++) {
        TrackingModel item = Items.get(j);
        if (item.id().toString().contains(id)) {
            isExist = true;
            break;
        }
    }
    // 如果不存在,再添加
    if (!isExist) {
        TrackingModel reg = new TrackingModel();
        reg.setId(id);
        // 这里可以安全添加
        Items.add(reg);
    }
}

方案2:使用迭代器的add方法

ArrayList的迭代器支持add方法,用它来添加元素不会触发异常,同时也能保证遍历的正确性:

JSONArray data = obj.getJSONArray("response");
for (int i = 0; i < data.length(); i++) {
    String id = data.getJSONObject(i).optString("id");
    boolean isExist = false;
    Iterator<TrackingModel> iterator = Items.iterator();
    while (iterator.hasNext()) {
        TrackingModel item = iterator.next();
        if (item.id().toString().contains(id)) {
            isExist = true;
            break;
        }
    }
    if (!isExist) {
        TrackingModel reg = new TrackingModel();
        reg.setId(id);
        // 这里不在迭代器遍历的循环内修改,直接用Items.add即可
        Items.add(reg);
    }
}

方案3:先收集待添加元素,遍历完成后批量添加

这种方式更高效,尤其是当集合元素较多时,能减少多次修改集合的开销:

JSONArray data = obj.getJSONArray("response");
List<TrackingModel> newItems = new ArrayList<>();
for (int i = 0; i < data.length(); i++) {
    String id = data.getJSONObject(i).optString("id");
    boolean isExist = false;
    for (TrackingModel item : Items) {
        if (item.id().toString().contains(id)) {
            isExist = true;
            break;
        }
    }
    if (!isExist) {
        TrackingModel reg = new TrackingModel();
        reg.setId(id);
        newItems.add(reg);
    }
}
// 遍历完成后批量添加到原集合
Items.addAll(newItems);

关于你问的外部方法

其实不需要专门写外部方法,只要解决遍历和修改的冲突问题就行。当然如果后续逻辑复杂,把添加元素的逻辑抽成外部方法是可以的,但核心还是要避免在遍历迭代器的时候直接修改集合。

另外,给你个优化建议:如果id是唯一标识,你可以用HashSet来存储已有的id,这样检查是否存在的效率会从O(n)降到O(1),比如:

Set<String> existingIds = new HashSet<>();
// 先把已有id存入Set
for (TrackingModel item : Items) {
    existingIds.add(item.id().toString());
}
JSONArray data = obj.getJSONArray("response");
for (int i = 0; i < data.length(); i++) {
    String id = data.getJSONObject(i).optString("id");
    if (!existingIds.contains(id)) {
        TrackingModel reg = new TrackingModel();
        reg.setId(id);
        Items.add(reg);
        existingIds.add(id);
    }
}

这样不仅避免了异常,还大幅提升了去重的效率。

内容的提问来源于stack exchange,提问作者BENN1TH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:45:07