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

为什么这个程序会产生异常?
如题,感觉这两个小程序逻辑上都讲得通。

第一个用跌代器来移除所有元素成功。
import java.util.*;

public class  Test_1
{
public static void main(String[] args)
{
List<String> a = new LinkedList<String>();
a.add("abc");
a.add("eee");
a.add("ooo");
a.add("fff");

     Iterator<String> aa = a.iterator();
     
      while(aa.hasNext())
      {
       aa.next();
       aa.remove(); //此处用跌代器来移除,成功了。
      
      }
System.out.println(a);      
}
}


第二个用用集合中的remove来移除,为什么不成功?
import java.util.*;

public class  Test_1
{
public static void main(String[] args)
{
List<String> a = new LinkedList<String>();
a.add("abc");
a.add("eee");
a.add("ooo");
a.add("fff");

        Iterator<String> aa = a.iterator();
        while(aa.hasNext())
    {
       String x = aa.next();
       a.remove(x);   //此处用集合中的remove来移除,为什么不成功?
      
    }
System.out.println(a);
           
}
}

------解决方案--------------------
这种迭代是快速失败的,你只能用iterator内置的方式删除啊,如果你自己删除,就快速失败了,可以看看JAVA api
------解决方案--------------------
可以试试看源码:
注:此指针非彼指针。

public boolean remove(Object o) {
     //二者都是通过寻找该元素实现删除的
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                 //看看unlink
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
    
    E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        //确定前后
        final Node<E> next = x.next; 
        final Node<E> prev = x.prev;
        if (prev == null) {//如果是第一个元素
            first = next;
        } else {
         //将前一个元素的后指针指向他的后一个元素
            prev.next = next;
            //该元素不再有前置指针
            x.prev = null;
        }
        if (next == null) {//如果是最后一个元素
            last = prev;
        } else {
         //将后一个元素的前指针指向自己的前一个元素。
            next.prev = prev;