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检查,以防有变。如果有变,则以异常抛出,所以就出现了上面的异常。

  • 相关阅读:
    合并vector里的内容,输出一个string
    免费矢量图标下载【转载】
    NX二次开发-UFUN打开选择文件夹对话框UF_UI_create_filebox
    Windows路径操作API函数学习【转载】
    NX二次开发-UFUN设置对象线型UF_OBJ_set_font
    NX二次开发CreateDialog函数在UI.hxx文件和WinUser.h中的冲突【转载】
    NX二次开发-UFUN将工程图中的点坐标映射到建模绝对坐标UF_VIEW_map_drawing_to_model
    NX二次开发-UFUN将建模绝对空间中的点映射到工程图坐标UF_VIEW_map_model_to_drawing
    NX二次开发-UFUN CSYS坐标系转换UF_CSYS_map_point
    VC操作Excel之基本操作(颜色等)【转载】
  • 原文地址:https://www.cnblogs.com/Profound/p/6934346.html
Copyright © 2011-2022 走看看