为什么像add(Object o),remove(Object o)这样的集合方法在迭代中无法移除或更新?

时间:2016-04-26 15:50:00

标签: java iterator

我必须检查0到10个数字的ArrayList集合中的数字是否均匀。使用Iterator,我必须在ArrayList内打印所有偶数,并从ArrayList中删除奇数。

package hemantdhanuka;

import java.util.*;

public class Iteratorr {

    public static void main( String [] args) {
        ArrayList v = new ArrayList ();
        for( int i = 0; i <= 10; i++ ) {
            v.add ( i );
        }
        System.err.println ( v );
        Iterator i = v.iterator ();
        /*while ( i.hasNext () ) {
            Integer a = ( Integer ) i.next ();
            if ( i % 2 == 0 ) {
                System.out.println ( i );
            } else {
                i.remove ();
            }
        }       
        System.out.println ( v );
        */
        while( i.hasNext () ) {
            Integer a = ( Integer) i.next ();
            if ( a % 2 == 0 ) {
                System.out.println ( a );
            } else {
                v.remove ( a );
            }
        }
        System.out.println ( v );
    }
}

我知道评论代码会正常运行,但非评论代码呢?如果我尝试使用ArrayList#remove(Obj o)ArrayList删除奇数,那么它就无效了。 WHY

3 个答案:

答案 0 :(得分:0)

它不起作用,因为您正在以超出迭代器知识的方式更改容器。

考虑ArrayList。它有&#34; n&#34;元素,以及返回迭代器的方法(依次返回每个&#34; n&#34;元素)。你可以编写自己的迭代器......

class MyArrayListIterator<T> implements Iterator<T> {
    private final ArrayList<T> list;
    private int index;

    MyArrayListIterator(ArrayList<T> lst) {
        list = lst;
        index = 0;
    }

    public boolean hasNext() {
        return index < list.size();
    }

    public T next() {
        return list.get(index++);
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}

假设该列表包含10,11,13,14

使用这个迭代器,直接删除奇数项(不使用迭代器的删除方法):

  • 10返回; index增加到1
  • 11返回;指数增加到2; 11从列表中删除。
  • 返回
  • 14(因为列表现在是&#34; 10,13,14和#34 ;,索引== 2的项目是14!)

注意迭代器&#34;跳过&#34;结束&#34; 13&#34;因为迭代器会推进每个调用,并且列表会将项目移动到较低的索引。

为了使迭代器在ArrayList被修改时正常运行,列表必须告诉所有迭代器在其上运行修改(可以有多个迭代器,即使没有线程)。或者,迭代器本身必须进行修改。

由于ArrayList不存储对其上运行的每个活动迭代器的引用,因此前一个选项是不可能的。相反,ArrayList维护一个简单的状态值,该状态值在对其进行修改时会发生变化。迭代器可以检查状态的意外更改,如果找到,可以抛出ConcurrentModificationException,以警告程序员他们的代码在集合上运行不正确。

注意&#34;可以检查&#34;并且&#34;可以扔上&#34;,上面。迭代器不是必须这样做的;这是&#34;尽力而为&#34;检查以帮助程序员避免错误的代码。

答案 1 :(得分:0)

最简单的答案是你使用if条件来检查for循环内部的偶数/奇数,我没有看到任何需要使用迭代器。

如果必须使用迭代器,那么创建2个ArrayLists并在条件下填充它们。

答案 2 :(得分:-1)

查看List.listIterator()。 ListIterator接口有一个remove()方法。