zoukankan      html  css  js  c++  java
  • 对JAVA集合进行遍历删除时务必要用迭代器

    0.情景引出

    对新手来说,遍历一个集合时难免会碰到删除操作,直接删除的话,肯定是要抛异常的

     1 public static void main(String[] args) {
     2 
     3         List<String> list = new ArrayList<>();
     4         for(int i=0;i<10;i++){
     5             list.add(String.valueOf(i));
     6         }
     7         System.out.println(list.toString());
     8         System.out.println("----------------------");
     9         for (String str:list){
    10             if(str.equals("5"))
    11                 list.remove(str);
    12         }
    13          //会抛出异常java.util.ConcurrentModificationException
    14 
    15     }

    异常的文档说明:

    所以呢,聪明的你,大概可以找解决方案了,我以前呢倒是会建一个临时的集合C2和需要删减的集合C1一致,一个循环,一个删减,对于迭代器好像都是敬而远之!!

    1.问题解决

    咳咳,这里呢,就是为了让自己明白点

     1 public static void main(String[] args) {
     2 
     3         List<String> list = new ArrayList<>();
     4         for(int i=0;i<10;i++){
     5             list.add(String.valueOf(i));
     6         }
     7         System.out.println(list.toString());
     8 
     9         System.out.println("----------------------");
    10 
    11         Iterator iter = list.iterator();
    12         while (iter.hasNext()){
    13             String str = (String) iter.next();
    14             if(str.equals("5"))
    15                 iter.remove();
    16                 //错误的写法,list.remove(str);,这种类似于上面的
    17         }
    18 
    19         System.out.println(list);
    20 
    21     }

    文章到此应该结束了。下面只是补充下,我自己对Iterator的理解

    2.扩展Iterator

      2.1 我们先来看一下Iterator的api解释:

    这个移除元素的特点看来是与生俱来的吧,

    2.2 我们再看一下ArrayList中的Iterator实现:

     1 private class Itr implements Iterator<E> {
     2    /**
     3     * Index of element to be returned by subsequent call to next.
     4     */
     5    int cursor = 0;
     6    /**
     7     * Index of element returned by most recent call to next or
     8     * previous.  Reset to -1 if this element is deleted by a call
     9     * to remove.
    10     */
    11    int lastRet = -1;
    12    /**
    13     * The modCount value that the iterator believes that the backing
    14     * List should have.  If this expectation is violated, the iterator
    15     * has detected concurrent modification.
    16     */
    17    int expectedModCount = modCount;
    18    public boolean hasNext() {
    19            return cursor != size();
    20    }
    21    public E next() {
    22            checkForComodification();
    23        try {
    24        E next = get(cursor);
    25        lastRet = cursor++;
    26        return next;
    27        } catch (IndexOutOfBoundsException e) {
    28        checkForComodification();
    29        throw new NoSuchElementException();
    30        }
    31    }
    32    public void remove() {
    33        if (lastRet == -1)
    34        throw new IllegalStateException();
    35            checkForComodification();
    36        try {
    37        AbstractList.this.remove(lastRet);
    38        if (lastRet < cursor)
    39            cursor--;
    40        lastRet = -1;
    41        expectedModCount = modCount;
    42        } catch (IndexOutOfBoundsException e) {
    43        throw new ConcurrentModificationException();
    44        }
    45    }
    46    final void checkForComodification() {
    47        if (modCount != expectedModCount)
    48        throw new ConcurrentModificationException();
    49    }
    50    }

    Iterator采用cursor来来维护自已的状态,而上ArrayList采用size属性来维护自已的状态

    当size出现变化时,cursor并不一定能够得到同步,除非这种变化是Iterator主动导致的。

    从上面的代码可以看到当Iterator.remove方法导致ArrayList列表发生变化时,他会更新cursor来同步这一变化。但其他方式导致的ArrayList变化,Iterator是无法感知的。ArrayList自然也不会主动通知Iterator们,那将是一个繁重的工作。Iterator到底还是做了努力:为了防止状态不一致可能引发的无法设想的后果,Iterator会经常做checkForComodification检查,以防有变。如果有变,则以异常抛出,所以就出现了上面的异常。

  • 相关阅读:
    帝国CMS采集
    帝国CMS常用资料
    IIS 支持PHP(与Apache环境共存)
    Firebug+Firefox 脚本调试
    javascript 参考
    [__NSCFString objectFromJSONString]: unrecognized selector sent to 解决办法
    大家好,我在CSDN开通了博客
    Apple MachO Linker Error
    ios 排序
    ios 二维码生成 扫瞄
  • 原文地址:https://www.cnblogs.com/Profound/p/6934346.html
Copyright © 2011-2022 走看看