迭代器和枚举之间的区别

时间:2014-02-26 10:00:46

标签: java collections iterator enumeration

请参阅以下代码

import java.util.Enumeration;
import java.util.Vector;

public class Modification_On_Eumeration {
    public static void main(String[] args) {
        Vector<Integer> vector = new Vector<Integer>();
        vector.add(1);
        vector.add(2);
        System.out.println(vector);
        Enumeration<Integer> enumeration = vector.elements();
        while (enumeration.hasMoreElements()) {
            Integer integer = (Integer) enumeration.nextElement();
            System.out.print(integer);
        }
        System.out.println();
        System.out.println("first loop finished");
        vector.add(3);
        while (enumeration.hasMoreElements()) {
            Integer integer1 = (Integer) enumeration.nextElement();
            System.out.println(integer1);
        }
    }
}

上面的代码工作正常,输出为:

[1, 2]
12
first loop finished
3

现在看下面的代码:

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class Fail_Safe_Iterator {
    public static void main(String[] args) {
        CopyOnWriteArrayList<Integer> copyOnWriteArrayList=new CopyOnWriteArrayList<Integer>();
        copyOnWriteArrayList.add(6);
        copyOnWriteArrayList.add(2);
        System.out.println(copyOnWriteArrayList);
        Iterator<Integer> iterator=copyOnWriteArrayList.iterator();
        while (iterator.hasNext()) {
            Integer integer = (Integer) iterator.next();
            System.out.println(integer);
        }
        System.out.println("first loop finished");
        copyOnWriteArrayList.add(5);
        while (iterator.hasNext()) {
            Integer integer = (Integer) iterator.next();
            System.out.println(integer);//why not printing 5
        }
    }
}

输出是:

[6, 2]
6
2
first loop finished

我正在学习java ..我怀疑是在添加3之后的第一个例子中,我能够回溯并打印它。但在第二个例子中,在添加5之后我无法回溯并打印它。这是什么原因? 是因为迭代器失败安全行为?或者它是枚举和迭代器之间的区别之一?帮助我......

3 个答案:

答案 0 :(得分:5)

CopyOnWriteArrayList根据支持列表的基础数组的当前状态创建一个新的Iterator

Java来源

 public ListIterator<E> iterator() {
         return new COWIterator<E>(getArray(), 0);
 }

此迭代器不包含创建后添加的元素,因为CopyOnWriteArrayList通过创建基础数组的新副本来执行变异操作(添加,设置等)。因此,在创建迭代器时,它会在该瞬间反射基础数组。

<强>修正

    System.out.println("first loop finished");
    copyOnWriteArrayList.add(5);

    //get the new iterator after adding
    iterator = copyOnWriteArrayList.iterator();

    while (iterator.hasNext()) {
        Integer integer = (Integer) iterator.next();
        System.out.println(integer);//why not printing 5
    }

答案 1 :(得分:1)

区别在于Iterator.remove()次操作,而Enumeration没有。{/ p>

此外,我们是在2014年,因此请勿使用VectorEnumeration;它们已经过时,只有旧版API仍在使用它们。

至于为什么你的程序以这种方式运行,这是由于CopyOnWriteArrayList的“写入时复制”:迭代器是用当前列表内容创建的;如果在创建迭代器后修改该列表,则不会看到修改。

答案 2 :(得分:0)

问题是您使用了CopyOnWriteArrayList类:

来自CopyOnWriteArrayList的java doc:

  

“快照”样式迭代器方法使用对状态的引用   创建迭代器时的数组。这个数组从不   在迭代器的生命周期中发生了变化,因此干扰就是   不可能,并且保证迭代器不会抛出   ConcurrentModificationException的。 迭代器不会反映出来   自迭代器以来添加,删除或更改列表   已创建。迭代器本身的元素更改操作(删除,   不支持set和add)。抛出这些方法   UnsupportedOperationException异常