移动迭代器语句使代码可编译

时间:2018-10-17 02:39:44

标签: java compilation iterator

我创建了一个代码,基本上只测试了大约。 ArrayLists的运行时。但是,如果将一行代码移到位置,则该代码将无法编译。这是编译的代码。

public class ArrayTest {

    public static void main(String []args) {
        ArrayListTest();
    }

    private static void ArrayListTest() {
        //initializes random variable, accumulator and iterator and ArrayList
        Random rand = new Random();
        Float accum = 0F;
        ArrayList<Float> al = new ArrayList<>();

        //finds time of program pre-running
        long startTime = System.currentTimeMillis();

        //Populates ArrayList
        for (int i = 0; i < 20000000; i++) al.add(rand.nextFloat());

        //finds time of program post-running
        long endTime = System.currentTimeMillis();

        //Iterates through ArrayList, summing elements
        Iterator<Float> itr = al.iterator();
        while(itr.hasNext()) {
            accum += itr.next();
        }

        //Finds time of summing ArrayList
        long sumEndTime = System.currentTimeMillis() - endTime;

        //Prints meaningful conclusion
        System.out.print("ArrayList takes: " + (endTime - startTime) / 1000.0 + " seconds to initialize.\n");
        System.out.print("ArrayList takes: " + (sumEndTime / 1000.0) + " second to sum. \n");
    }
}

但是,如果移动“ Iterator itr = al.iterator();”,在声明arraylist之后的右边,它不会编译。为什么会这样?

1 个答案:

答案 0 :(得分:1)

如果将迭代器的创建移动到ArrayList创建之后,您的代码编译就很好了,代码将运行,但是它将抛出ConcurrentModificationException,因为您在创建 之后更改列表迭代器,并且不使用迭代器。这将使迭代器处于无效状态。

如果您在此处创建迭代器:

ArrayList<Float> al = new ArrayList<>();
Iterator<Float> itr = al.iterator();

,然后在此处添加到ArrayList:

// Populates ArrayList
for (int i = 0; i < 20000000; i++)
    al.add(rand.nextFloat());

迭代器现在正尝试遍历自创建以来已更改的集合,这将导致在此引发ConcurrentModificationException:

while (itr.hasNext()) {
    accum += itr.next();
}   

要解决此问题,请在创建迭代器后仅使用迭代器修改该集合。主要是从集合中删除项目时完成。如果需要添加项目,则需要使用ListIterator而不是普通的香草Iterator,或者只需在填充集合后 创建您的迭代器。

例如

ArrayList<Float> al = new ArrayList<>();
// Iterator<Float> itr = al.iterator();       
ListIterator<Float> listItr = al.listIterator();

long startTime = System.currentTimeMillis();

for (int i = 0; i < 20000000; i++) {
    // al.add(rand.nextFloat());
    listItr.add(rand.nextFloat());  // add with the ListIterator
}

long endTime = System.currentTimeMillis();

while (listItr.hasNext()) {
    accum += listItr.next();
}

此外,您还需要阅读:What is the difference between run-time error and compiler error?
因为这种区别非常重要,尤其是在此网站上询问时。它们是错误的两种截然不同的大类,并且在大多数情况下,它们不会重叠。