remove
void remove()从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改了该
迭代器所指向的 collection,则迭代器的行为是不确定的。 

解决方案 »

  1.   

    用remove删除元素之后,该Collection不就发生改变了吗,那么该迭代器不就失效了吗
      

  2.   

    用remove删除元素之后,该Collection不就发生改变了吗,那么该迭代器不就失效了吗是的,一般iterator中remove会经常出错,但也不是一定就出错,尽量不要这么使用。
      

  3.   

    这个,我也想知道,瞅瞅源码吧单步调试,进入到这里:private abstract class HashIterator<E> implements Iterator<E> {
            Entry<K,V> next; // next entry to return
            int expectedModCount; // For fast-fail
            int index; // current slot
            Entry<K,V> current; // current entry        HashIterator() {
                expectedModCount = modCount;
                if (size > 0) { // advance to first entry
                    Entry[] t = table;
                    while (index < t.length && (next = t[index++]) == null)
                        ;
                }
            }        public final boolean hasNext() {
                return next != null;
            }        final Entry<K,V> nextEntry() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                Entry<K,V> e = next;
                if (e == null)
                    throw new NoSuchElementException();            if ((next = e.next) == null) {
                    Entry[] t = table;
                    while (index < t.length && (next = t[index++]) == null)
                        ;
                }
        current = e;
                return e;
            }
    //调用的这个方法
            public void remove() {            if (current == null)
                    throw new IllegalStateException();
    //玄机就在这里:expectedModCount,拷贝网上找来的说明,
    /** 
    *在Iterator的内部有个expectedModCount 变量, 
    *该变量每次初始化*Iterator的时候等于ArrayList的modCount,modCount记录了对ArrayList的结构修改次数, 
    *在通过Iterator对ArrayList进行结构的修改的时候都会将expectedModCount 与modCount同步, 
    *但是如果在通过Iterator访问的时候同时又通过索引的方式去修改ArrayList的结构的话, 
    *由于通过索引的方式只会修改modCount不会同步修改expectedModCount 就会导致 
    *modCount和expectedModCount 不相等就会抛ConcurrentModificationException, 
    *这也就是Iterator的fail-fast,快速失效的。所以只要采取一种方式操作ArrayList就不会出问题, 
    *当然ArrayList不是线程安全的,此处不讨论对线程问题。 * http://sushe1424.iteye.com/blog/1110796
    */  
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                Object k = current.key;
                current = null;
                HashMap.this.removeEntryForKey(k);
                expectedModCount = modCount;
            }    }
     /**
         * Removes and returns the entry associated with the specified key
         * in the HashMap.  Returns null if the HashMap contains no mapping
         * for this key.
         */
        final Entry<K,V> removeEntryForKey(Object key) {
            int hash = (key == null) ? 0 : hash(key.hashCode());
            int i = indexFor(hash, table.length);
            Entry<K,V> prev = table[i];
            Entry<K,V> e = prev;        while (e != null) {
                Entry<K,V> next = e.next;
                Object k;
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k)))) {
                    modCount++;
                    size--;
                    if (prev == e)
                        table[i] = next;
                    else
                        prev.next = next;
                    e.recordRemoval(this);
                    return e;
                }
                prev = e;
                e = next;
            }        return e;
        }看看和直接删除有什么不一样:
    直接删除先调用hashset里的,没有对expectedModCount做同步,这就会出错了!
     public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
        }
    map.remove(o)其实也是hashMap里的removeEntryForKey()
       public V remove(Object key) {
            Entry<K,V> e = removeEntryForKey(key);
            return (e == null ? null : e.value);
        }