java - ArrayList::iterator 中的 i >= elementData.length 是多余的吗?

标签 java arraylist iterator

这是 ArrayList::Itr 的下一个方法

public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}

它包含一个 if 语句:

if (i >= elementData.length)
    throw new ConcurrentModificationException();

我认为除非用户调用trimToSize方法,否则很少会发生i >= elementData.length的情况。而且我认为 if 语句是多余的,因为 checkForCommodification 可以处理所有事情。 我说得对吗?

最佳答案

不,不是。如果使用另一个线程,ArrayListtrimTosize之后使用

checkForComodification();

...但是之前

Object[] elementData = ArrayList.this.elementData;

ArrayList.this.elementData 在此期间可能已更改(收到新的数组引用)。因此,在将 ArrayList.this.elementData 抓取到局部变量 (elementData) 中之后,检查数组中的索引是否有效是正确且必要的。 。代码完成此操作后,它将具有对其要查找的数组的本地引用 (elementData) 和索引的本地变量 i)。如果对 ArrayList.this.elementData 进行更改,则此时需要该代码才能引发正确的异常 (ConcurrentModificationException),而不是 ArrayIndexOutOfBounds在代码抓取之前,它使索引无效。

例如,请注意 ** 行:

    public E next() {
        checkForComodification();
        int i = cursor;                                    // ***
        if (i >= size)                                     // ***
            throw new NoSuchElementException();            // ***
        Object[] elementData = ArrayList.this.elementData; // ***
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

其他线程可能会进入其中。只有当我们有了自己对要使用的数组的引用(最后一个 ** 行完成后),我们才知道引用不会改变(因为它是本地的)。

关于java - ArrayList::iterator 中的 i >= elementData.length 是多余的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38239985/

相关文章:

java - Eclipse:如何在不按 ctrl+shift+space 的情况下自动打开上下文信息

c# - 为什么我们不能在 C# 中使用 Iterator StateMachine Attribute?

c++ - constexpr 使用标准库算法

java - 如何退出java中的返回循环?

Java 最佳实践 new 与 .create()

java - 用无穷级数计算圆周率

java - List<List<Integer>> ArrayList 初始化不适用于 new 运算符 Java

java - Double 不能取消引用 [Arraylist]

java - 使用 BufferedWriter 写入 TXT 文件 - Java

python - 遍历字符串的行