日期:2014-05-20  浏览次数:20876 次

请教现在正在公司做Java项目的前辈们,迭代器中的三个方法的用法。
在“java.util”包下有一个“Iterator”接口,它里面有三个方法“hasNext()”“next()”和“remove()”可供使用。前两个方法我试用过,用的时候很顺利,但是第三个方法“remove()”很是令我费解。下面这段代码仅仅是我自己练习用的,小弟是初学者,且刚学集合,可能代码写得让各位前辈见笑了。代码如下(忽略“泛型”):

Java code
package day08.part1;

import java.util.*;

public class Test {
    public static void main(String[] args) {
        List list = new LinkedList();
        list.add("Ⅰ");
        list.add("Ⅱ");
        list.add("Ⅲ");
        list.add("Ⅳ");
        list.add("Ⅴ");
        list.add("Ⅵ");
        list.add("Ⅶ");
        list.add("Ⅷ");
        list.add("Ⅸ");
        list.add("Ⅹ");
        
        Iterator it = list.iterator();
        
        System.out.print("list = ");
        while(it.hasNext()){
            System.out.print("[" + it.next() + "]");
        }
        System.out.println();
        
        list.remove("Ⅴ");
        
        System.out.print("lsit = ");
        while(it.hasNext()){
            System.out.print("[" + it.next() + "]");
        }
        System.out.println();
    }
}


输出的结果如下:
list = [Ⅰ][Ⅱ][Ⅲ][Ⅳ][Ⅴ][Ⅵ][Ⅶ][Ⅷ][Ⅸ][Ⅹ]
lsit = Exception in thread "main" java.util.ConcurrentModificationException
  at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
  at java.util.LinkedList$ListItr.next(Unknown Source)
  at day08.part1.Test.main(Test.java:31)

于是我查看在“API”中“java.util.Iterator”类的三个方法的介绍(我看的是中文版),前两个方法还比较能理解,但是第三个方法“remove()”介绍说:“从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改了该迭代器所指向的集合,则迭代器的行为是不明确的。”对此我很费解。

我的问题如下:
1.输出时抛出的那个异常是什么意思,我哪里做错了?
2.在“API”中“java.util.Iterator”类的“remove()”方法的介绍,请各位前辈用最简单的“人话”来将其解释一下。
3.“Iterator”接口中的三个方法在公司的正规项目中一般都怎么用(请教正确的用法),还是根本不用?
4.高分、虚心、虔诚、期盼着在Java开发工作的第一线的各位前辈们的到来,小弟将不胜感激!

------解决方案--------------------
Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。

------解决方案--------------------
就是说你取得了迭代器之后还直接修改了原容器对象 这是不合适的 再次使用迭代器后会报异常
------解决方案--------------------
Java code

import java.util.*;

public class Test123 {
    public static void main(String[] args) {
        List list = new LinkedList();
        list.add("Ⅰ");
        list.add("Ⅱ");
        list.add("Ⅲ");
        list.add("Ⅳ");
        list.add("Ⅴ");
        list.add("Ⅵ");
        list.add("Ⅶ");
        list.add("Ⅷ");
        list.add("Ⅸ");
        list.add("Ⅹ");
        
        Iterator it = list.iterator();
        
        System.out.print("list = ");
        while(it.hasNext()){
            String s= (String)it.next();
            System.out.print("[" +s + "]");
            if(s.equals("Ⅴ")){
                it.remove();//一次next只能使用一次 不能多用
            }
        }
        System.out.println();
 
        it=list.iterator();//迭代器到末尾了 需要重新获取
        System.out.print("lsit = ");
        while(it.hasNext()){
            System.out.print("[" + it.next() + "]");
        }
        System.out.println();
    }
}

------解决方案--------------------
每次调用过next后才可以调用remove