今天Alei写了一段让人感到很是疑惑的代码:java
public static void main(String[] args) { Collection c = new ArrayList(); c.add(new Name("fff1", "lll1")); c.add(new Name("f1", "l1")); c.add(new Name("fff3", "lll3")); for(Iterator i = c.iterator(); i.hasNext();) { Name name = (Name)i.next(); if(name.getFirstName().length() < 3) { i.remove(); // c.remove(name); //此方法会产生例外(异常)? } } System.out.println(c); } class Name { private String firstName, lastName; public Name(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String toString() { return firstName + " " + lastName; } public boolean equals(Object obj) { if(obj instanceof Name) { Name name = (Name)obj; return firstName.equals(name.firstName) && lastName.equals(lastName); } return super.equals(obj); } public int hashCode() { return firstName.hashCode(); } }
在 main 方法里的代码略显诡异,众所周知,在使用迭代器进行遍历时,如有删除容器里某元素的操做,必定要使用这个容器类迭代器的 remove() 方法,而不能使用容器对象的 remove() 方法。this
认真看下 ArrayList 类的源码就能发现:code
ArrayList 采用 size 属性来维护自已的状态,而 Iterator 采用 cursor(游标)来来维护自已的状态。对象
当 size 出现变化时,cursor 并不必定可以获得同步,除非这种变化是 Iterator 主动致使的。当 Iterator.remove() 方法致使 ArrayList 列表发生变化时,他会更新 cursor 来同步这一变化。但其余方式致使的 ArrayList 变化,Iterator 是没法感知的。ArrayList 天然也不会主动通知 Iterator 们,那将是一个繁重的工做。Iterator 到底仍是作了努力:为防止状态不一致可能引起的“没法设想的后果”,Iterator 会常常作 checkForComodification 检查,以防有变。若是有变,则抛出异常。rem
若是对正在被迭代的集合进行结构上的改变(即对该集合使用 add、remove 或 clear 方法),那么迭代器就再也不合法(而且在其后使用该迭代器将会有 ConcurrentModificationException 异常被抛出)。get
若是使用迭代器本身的 remove 方法,那么这个迭代器就仍然是合法的。同步
然并卵,当我使用 c.remove() 方法时,程序尽然没有抛出异常!!!!!!源码
因而我又敲出下面代码并运行:hash
List<String> famous = new ArrayList<String>(); famous.add("liudehua"); famous.add("huaiyirensheng"); famous.add("liushishi"); famous.add("tangwei"); for (String s : famous) { if (s.equals("huaiyirensheng")) { famous.remove(s); } } //以上代码中的循环等同于: for(Iterator<String> it = famous.iterator();it.hasNext();){ String s = it.next(); if(s.equals("huaiyirensheng")){ famous.remove(s); } }
因而抛出异常:it
java.util.ConcurrentModificationException
这下我就懵B了,这是怎么回事呀?我开始怀疑本身的人生!!!!!!!
上面的循环若是改为下面这样:
for (int i = 0; i < famous.size(); i++) { String s = famous.get(i); if (s.equals("huaiyirensheng")) { famous.remove(s); } }
那跟迭代器半毛钱关系都没有了!难道我一开始写的那些代码跟迭代器没半毛钱关系?跪求大神解答我这个小白的低级问题!