有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我创建了一个代码,基本上只测试ArrayList的大约运行时。但是,如果将一行代码移动到某个点,代码将不会编译。下面是编译的代码

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");
    }
}

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


共 (1) 个答案

  1. # 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,而不是普通的迭代器,或者在填充集合后创建迭代器

    例如

    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?
    因为这种区别非常重要,尤其是在这个网站上提问时。它们是两个非常不同的大错误类别,在大多数情况下,它们并不重叠