zoukankan      html  css  js  c++  java
  • 删除 List 元素的三种正确方法

    // 每次都会计算list.size()比较耗费性能
            public static void remove1 (List < String > list, String target){
                for (int i = list.size() - 1; i >= 0; i--) {
                    String item = list.get(i);
                    if (target.equals(item)) {
                        list.remove(item);
                    }
                }
                print(list);
            }
    

     

    //通过 CopyOnWriteArrayList 解决了 List的并发问题。每次remove的都是复制出的list
            public static void remove2 (ArrayList < String > list, String target){
                final CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<String>(list);
                for (String item : cowList) {
                    if (item.equals(target)) {
                        cowList.remove(item);
                    }
                }
                print(cowList);
            }
    

    Iterator的定义代码

            public static void remove3 (List < String > list, String target){
                Iterator<String> iter = list.iterator();
                while (iter.hasNext()) {
                    String item = iter.next();
                    if (item.equals(target)) {
                        iter.remove();
                    }
                }
                print(list);
            }
    

      

     private class Itr implements Iterator<E> {
                int cursor; // index of next element to return
                int lastRet = -1; // index of last element returned; -1 if no such
                int expectedModCount = modCount;
    
                public boolean hasNext() {
                    return cursor != size;
                }
    
                @SuppressWarnings("unchecked")
                public E next() {
                    checkForComodification();
                    int i = cursor;
                    if (i >= size) throw new NoSuchElementException();
                    Object[] elementData = ArrayList.this.elementData;
                    if (i >= elementData.length) throw new ConcurrentModificationException();
                    cursor = i + 1;
                    return (E) elementData[lastRet = i];
                }
    
                public void remove() {
                    if (lastRet < 0) throw new IllegalStateException();
                    checkForComodification();
                    try {
                        ArrayList.this.remove(lastRet);
                        cursor = lastRet;
                        lastRet = -1;
                        expectedModCount = modCount;
                    } catch (IndexOutOfBoundsException ex) {
                        throw new ConcurrentModificationException();
                    }
                }
    
                final void checkForComodification() {
                    if (modCount != expectedModCount) throw new ConcurrentModificationException();
                }
            }
    

    通过代码我们发现 Itr 是 ArrayList 中定义的一个私有内部类,
    在 next、remove方法中都会调用 checkForComodification 方法,该方法的作用是判断 modCount != expectedModCount是否相等,如果不相等则抛出ConcurrentModificationException异常。
    每次正常执行 remove 方法后,都会对执行expectedModCount = modCount赋值,保证两个值相等,那么问题基本上已经清晰了,在 foreach 循环中执行 list.remove(item);,对 list 对象的 modCount 值进行了修改,而 list 对象的迭代器的 expectedModCount 值未进行修改,因此抛出了ConcurrentModificationException异常。

  • 相关阅读:
    MongoDB+Lucence.net
    hubble+sqlserver
    C# 设计模式 1 接口模式 1.1 适配器模式 IT
    SQLServer2005 中 XML类型方法中 XQuery中变量的参数化匆忙整理 IT
    DoNET 类库设计准则01 名称规则 IT
    GMRES在matlab中的描述
    矩阵良态与病态
    调试vc++的一点感悟
    基于GramSchmidt正交法的广义极小残量法(GMRES)
    VC6 vs2003 vs2005 使用技巧(转)
  • 原文地址:https://www.cnblogs.com/muyuchengguang/p/11305202.html
Copyright © 2011-2022 走看看