zoukankan      html  css  js  c++  java
  • ConcurrentModificationException

    突然抛了一个concurrentModificationException错误,Iterator的一个基本概念没有掌握导致的这个错误,就是在Iterator的实现类。比如Hashtable里面的内部类
     private class Enumerator<T> implements Enumeration<T>, Iterator<T>

    会在next,或者remove的时候检查当前集合是否会在修改状态,如果是的话,就会抛出 ConcurrentModificationException,而他自己remove则是使用了同步的方法,而且同步了modCount;expectedModCount;

     1 public T next() {
     2      if (modCount != expectedModCount)
     3          throw new ConcurrentModificationException();
     4      return nextElement();
     5  }
     6 
     7 
     8 public void remove() {
     9      if (!iterator)
    10         throw new UnsupportedOperationException();
    11      if (lastReturned == null)
    12         throw new IllegalStateException("Hashtable Enumerator");
    13      if (modCount != expectedModCount)
    14         throw new ConcurrentModificationException();
    15 
    16      synchronized(Hashtable.this) {
    17         Entry[] tab = Hashtable.this.table;
    18         int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;
    19 
    20      for (Entry<K,V> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
    22       if (e == lastReturned) {
    23          modCount++;
    24          expectedModCount++;
    25          if (prev == null)
    26             tab[index] = e.next;
    27          else
    28             prev.next = e.next;
    29          count--;
    30          lastReturned = null;
    31          return;
    32       }
    33      }
    34      throw new ConcurrentModificationException();
    35      }
    36     }
    37     }
    而自己在next的同时,修改了这个集合,导致了这个错误的出现
    在Map或者Collection的时候,不要用它们的API直接修改集合的内容,如果要修改可以用Iterator的remove()方法,例如:
    1 public void setReparation( Reparation reparation ) {
    2         for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparations为Collection
    3             Reparation repa = (Reparation)it.next();
    4             if (repa.getId() == reparation.getId()){
    5                 this.reparations.remove(repa);
    6                 this.reparations.add(reparation);
    7             }
    8         }
    9    }
    如上写会在运行期报ConcurrentModificationException,可以如下修改:
     1  public void setReparation( Reparation reparation ) {
     2         boolean flag = false;
     3         for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparations为Collection
     4             Reparation repa = (Reparation)it.next();
     5             if (repa.getId() == reparation.getId()){
     6                 it.remove();
     7                 flag = true;
     8                 break;
     9             }
    10         }
    11         if(flag){
    12           this.reparations.add(reparation);
    13         }
    14     }

    原文摘自 alreal 

  • 相关阅读:
    VS2012程序打包部署详解
    C# 实现客户端程序自动更新
    C# dev gridcontrol中添加checkbox复选框
    sql server 修改表结构
    sql server 日期转换函数 convert()
    C# devExpress BandedGridView属性 备忘
    sql server 行转列 Pivot UnPivot
    c# 动态产生控件 注册动态控件事件
    阿里云镜像
    git 拉去代码要求密码 解决方法:生成gitLab公钥
  • 原文地址:https://www.cnblogs.com/timelyxyz/p/2595497.html
Copyright © 2011-2022 走看看