java - 无法弄清楚为什么它会抛出 ConcurrentModificationException

标签 java loops exception concurrentmodification

我遇到了 ConcurrentModificationException,但不知道为什么。我知道尝试使用 for 循环迭代列表并删除循环 block 内的元素是个坏主意,并且可能会引发此类异常,但我不知道如何在我的情况下修复它。

 private static final List<Integer> originalList = new ArrayList<>();

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            originalList.add(i);
        }


        final int MAX_GROUP_SIZE = 5;
        int partitionSize = 4;

        List<List<Integer>> partitions = new LinkedList<>();

        for (int i = 0; i < originalList.size(); i += partitionSize) {
            partitions.add(originalList.subList(i,
                    Math.min(i + partitionSize, originalList.size())));
        }

        int lastGroupSize = partitions.get(partitions.size() - 1).size();

        if (lastGroupSize < partitionSize && partitions.size() > lastGroupSize){
            List<Integer> lastGroup = partitions.remove(partitions.size() - 1);
            for (int i = 0; i < lastGroupSize; i++) {
                partitions.get(i).add(lastGroup.get(i));
            }
        }
        System.out.println("GROUPS: " + partitions.size());
        printGroups(new LinkedList<>(partitions));
    }

最佳答案

问题是您调用subList()不要创建新列表。正如 javadoc 所说:

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive.

javadoc 还说:

The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list.

当您调用partitions.get(i).add(...)时,您在结构上修改originalList,导致错误。

我不相信你是故意的,所以要解决这个问题,你只需要确保你的子列表独立于原始列表,即副本,这很容易做到:

new ArrayList<>(originalList.subList(...))

使用ArrayList(Collection)构造函数将创建子列表的副本。

因此,更改此声明:

partitions.add(originalList.subList(i,
        Math.min(i + partitionSize, originalList.size())));

对此:

partitions.add(new ArrayList<>(originalList.subList(i,
        Math.min(i + partitionSize, originalList.size()))));

关于java - 无法弄清楚为什么它会抛出 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51655246/

相关文章:

java - 切换按钮分配 double 值时出现致命异常 : java. lang.NumberFormatException

java - 如何在 60 秒后停止 java 中正在运行的方法

java - Jboss 和 Spring 中的 Logback 经典

c++ - 如何从文本文件加载链表?

python - for循环中的条件

java - 如何将两个数组合并成各自的二维数组?

python - UnboundLocalError : local variable 'e' referenced before assignment

java - 如何通过同一网络的 Android(就像 Gmote 2.0 所做的那样)在计算机上播放 mp3 文件?

java - 将 shell 脚本转换为 jar 文件

c++ - 在堆上分配异常有什么陷阱吗?