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

遍历列表时移除子列表:元素计数与范围移除异常问题

解决有序列表中限制元素出现次数并避免ConcurrentModificationException的问题

嘿,我完全懂你遇到的痛点——要处理有序列表里的元素出现次数,只保留最多m次,不能像removeAll那样把所有相同元素都删掉,结果用subList.clear()或者普通迭代器移除的时候还触发了ConcurrentModificationException对吧?

先说说为什么会出现这个异常:当你在遍历列表(比如用foreach循环或者普通的Iterator遍历)的同时,直接修改原列表(比如调用list.remove()),或者操作原列表的子视图(subList)时,列表的修改次数和迭代器维护的版本号不一致,就会抛出这个异常。

下面给你两种靠谱的解决方案,都是针对有序列表(相同元素连续)的场景:

方法一:使用迭代器安全移除

因为列表是有序的,相同元素会连续出现,我们可以用迭代器跟踪当前元素的出现次数,超过m次时用迭代器自带的remove()方法——这个方法是安全的,它会同步迭代器和列表的修改状态:

public static List<Integer> controlOccurrences(List<Integer> sortedArr, int m) {
    if (sortedArr == null || sortedArr.isEmpty() || m <= 0) {
        return new ArrayList<>();
    }

    Iterator<Integer> iterator = sortedArr.iterator();
    Integer prev = iterator.next();
    int count = 1;

    while (iterator.hasNext()) {
        Integer current = iterator.next();
        if (current.equals(prev)) {
            count++;
            // 超过m次时,用迭代器安全移除当前元素
            if (count > m) {
                iterator.remove();
            }
        } else {
            // 遇到新元素,重置计数和前一个元素
            prev = current;
            count = 1;
        }
    }
    return sortedArr;
}

方法二:利用子列表批量清理指定范围

这种方法先找到每个连续相同元素的区间,然后直接用subList清理超出m次的部分,全程用索引操作,避开迭代器的版本冲突:

public static List<Integer> controlOccurrences(List<Integer> sortedArr, int m) {
    if (sortedArr == null || sortedArr.isEmpty() || m <= 0) {
        return new ArrayList<>();
    }

    int i = 0;
    while (i < sortedArr.size()) {
        Integer current = sortedArr.get(i);
        int j = i + 1;
        // 找到当前元素连续出现的最后位置
        while (j < sortedArr.size() && sortedArr.get(j).equals(current)) {
            j++;
        }
        // 如果出现次数超过m,清理从i+m到j的所有元素
        if (j - i > m) {
            sortedArr.subList(i + m, j).clear();
            // 清理后列表长度变短,直接跳到保留的最后一个元素位置
            i += m;
        } else {
            // 没超过次数,跳到下一个不同元素的位置
            i = j;
        }
    }
    return sortedArr;
}

注意事项

  • 如果你的原列表是不可修改的(比如通过Collections.unmodifiableList创建的),上面两种方法都会抛出UnsupportedOperationException,这时候需要先创建一个原列表的副本:List<Integer> mutableList = new ArrayList<>(sortedArr);,再对副本进行操作。
  • 两种方法都依赖列表是有序且相同元素连续的前提,这和你代码里的sortedArr参数对应,完全适配你的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:10:24