1

Я получаю ConcurrentModificationException в следующем фрагменте кода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); 
      } 
     } 
     } 
    } 
} 

Пожалуйста, помогите мне в этом.

+0

Какую коллекцию вы используете? – subodh

+0

Пожалуйста, конвертируйте вкладки в пробелы в свой код, прежде чем вставлять их в редактор здесь. В противном случае ваш код будет трудно читать, уменьшая ваши шансы получить полезную помощь. –

ответ

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(); 
0

Действительно ли это в многопоточной среде? Если да, используйте поточно-безопасные коллекции. CopyOnWriteArrayList или Collections.synchronizedList

Смежные вопросы