[英]Why the API throws Concurrent Modification Exception in next() of list iterator of the sub list in ArrayList?
This is in reference to the first level sub list of an arraylist. 这是参考arraylist的第一级子列表。
We have this source code- 我们有此源代码-
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor; // initially cursor is set to 0
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException(); // WHY?
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
Why throw a ConcurrentModificationException
instead of IndexOutOfBoundsException
? 为什么抛出
ConcurrentModificationException
而不是IndexOutOfBoundsException
?
Why concurrent? 为什么要并发?
NOTE:- 注意:-
I am still struggling with the design part. 我仍在努力设计部分。
This is in reference to the comment by @Kayaman 这是参考@Kayaman的评论
Consider the below arraylist and its sublist- 考虑下面的arraylist及其子列表-
el original sublist
0 a[0]
10 a[1]
20 a[2] s[0]
30 a[3] s[1]
40 a[4] s[2]
50 a[5] s[3]
60 a[6] s[4]
70 a[7]
80 a[8]
90 a[9]
Every sublist has 2 instance variables 每个子列表都有2个实例变量
parent offset - diff b/w the first index location of parent and sub list.
父级偏移量-diff黑白父级和子级列表的第一个索引位置。
offset - diff b/w the first index location of original and sub list.
offset-diff b / w 原始列表和子列表的第一个索引位置。
There is internally an array elementData
which backs this arraylist
Even if some thread removes
an element from the original arraylist (concurrent modification), the size gets reduced by 1
, but the length
of elementData remains the same. 内部有一个支持此
arraylist
的数组elementData
即使某些线程从原始arraylist中removes
了一个元素(并发修改),其大小也减小了1
,但是elementData的length
保持不变。
fast remove
internally c/d by remove(Object)
- 通过
remove(Object)
内部fast remove
c / d-
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
I see that this condition will never be fulfilled- offset + i >= elementData.length
even after removal concurrently. 我看到永远不会满足此条件-即使同时删除后,
offset + i >= elementData.length
。
Any suggestions? 有什么建议么?
Because on creation of the Sublist
, a range check is performed: 因为在创建
Sublist
,将执行范围检查:
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
So the Sublist
will never go beyond the end of the source list. 因此,
Sublist
列表永远不会超出源列表的末尾。
Therefore, offset + i
will always be inside the valid range of the original List
except it has been modified in the meantime. 因此,
offset + i
始终在原始List
的有效范围内, 除非同时已对其进行了修改。
Note that Sublist
takes any AbstractList<>
as its source List
; 注意
Sublist
将任何AbstractList<>
作为其源List
; so even if ArrayList
itself does not shrink its backing array on a remove, a subclass might do so - which would cause Sublist
to be incorrect here. 因此,即使
ArrayList
本身在删除时不收缩其后备数组,子类也可能这样做-这将导致Sublist
在此处不正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.