java.util.concurrentmodificationexception 当在循环中 给List 添加对象或者 remove 对象是时候

最近在项目中再循环中删除当前list 的对象或者添加list的对象的时候   报了这个错误。

在Console 中可以发现是这个方法中报了错误:

checkForComodification()

/**
     * An optimized version of AbstractList.Itr
     */
    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();
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

从这里可以看到,这里会比较现在的 Count 是否是期待的   有点类似于 CAS 的思想 , 就是会比较下List 的坐标。

那么我们该如何解决呢?

对于 Remove 

我们可以 把List  转换为  iterator  , 利用While  来进行 remove  。

例子:

Iterator<ImportResultEachRow<Test>> iterator = RecordList.iterator();
while (iterator.hasNext()) {
            ImportResultEachRow<Test> item = iterator.next();
            if (StringUtils.isNotBlank(item.getTargetObject().getDeleted())
                    && !StringUtils.equals(item.getTargetObject().getDeleted().toUpperCase(), "Deleted")){
                iterator.remove();
            }
        }

这样子就可以在List 循环中删除掉  元素了。

对于Add()

同样的 我们也可以进行转换, 但是iterator 是没有提供Add 的方法, 所以我们可以用  ListIterator 这样子我们就可以使用add  方法来进行 添加元素了。


ListIterator<ReportDTO> iterator = SameValueDays.listIterator();
while (iterator.hasNext()) {
            ReportDTO oneRowInfo = iterator.next();
                    if (oneRowInfo.getAmount() == null && !hasOutward) {
                        ReportDTO otherRowInfo = new ReportDTO();
                        iterator.add(otherRowInfo ); 
  }
}

这样子就可以 放心的在循环中 添加了。

 对了 我这个方案 只能在  单线程中使用。  如果是多线程  请参考下面的文章。

引用文章:http://www.cnblogs.com/dolphin0520/p/3933551.html

原文地址:https://www.cnblogs.com/mythdoraemon/p/10214435.html