1

次のコードで ConcurrentModificationException を取得します

コードを実行するとうまくいきましたが、突然例外がスローされました。リストの変更が原因だと思いますが、修正方法がわかりません

if (myRulesIncr!=null)
{
    Iterator itReceivedRules = myRulesIncr.iterator();
    while (itReceivedRules.hasNext())
    {
      RuleModel currentReceived = (RuleModel) itReceivedRules.next();
      if (receivedRulesExisting!=null)
      {
        Iterator itReceivedRulesExisting = receivedRulesExisting.iterator();
        while (itReceivedRulesExisting.hasNext())
        {
            RuleModel currentExisting = (RuleModel) itReceivedRulesExisting.next();

            if(currentExisting.getRuleId().equals(currentReceived.getRuleId()))
            {
                //TODO:replace the rule else add it.
                if(currentReceived.getStatus()!="D")
                { 
                    //replace the existing rule with the new one
                    receivedRulesExisting.remove(currentExisting);
                    receivedRulesExisting.add(currentReceived);
                } 
                else
                {
                    receivedRulesExisting.remove(currentExisting); 
                }
            }
            else
            {
                //Add the new rule to the existing rules
                receivedRulesExisting.add(currentReceived);
            }
        }
      }
    }
}

これで私を助けてください。

4

2 に答える 2

4

ConcurrentModificationException反復されているコレクションが外部で、つまり反復子を介さずに変更された場合にスローされます。Iterator.remove()したがって、この例外を回避するために使用する必要があります。さらに、繰り返しながらコレクションに直接追加する代わりに、追加するアイテムを別のコレクションに保存してから、後で追加します。

  List<RuleModel> toBeAdded = new ArrayList<RuleModel>();

  if(currentReceived.getStatus()!="D")
  { 
      //replace the existing rule with the new one
      itReceivedRulesExisting.remove();
      toBeAdded.add(currentReceived);
  } 
  else
  {
      itReceivedRulesExisting.remove(); 
  }

  ...
  // after the loop terminated:
  receivedRulesExisting.addAll(toBeAdded);

また、ジェネリック コレクションを使用したことにも注意してください。型の安全性を確保し、次のようなダウンキャストを取り除くために、ジェネリック コレクションを使用することをお勧めします。

Collection<RuleModel> myRulesIncr = ...
...
Iterator<RuleModel> itReceivedRules = myRulesIncr.iterator();
...
RuleModel currentReceived = itReceivedRules.next();
于 2012-04-02T13:50:40.327 に答える
0

これはマルチスレッド環境ですか?はいの場合は、スレッドセーフなコレクションを使用してください。CopyOnWriteArrayListまたCollections.synchronizedList

于 2012-04-02T13:55:32.447 に答える