我遇到了 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/