2012-11-28 2 views
0

데이터베이스에서 정보를 수집하는 정상적인 데이터베이스 호출이 있습니다. 이러한 정보를 사용하여 내 개체 (CallQueue)를 만든 다음 이러한 개체를 목록에 추가하면 목록이 반환됩니다.ConcurrentModificationExecption

갑자기 내가 dublicates를 만들었 기 때문에 갑자기 원래 코드가 의도 한대로 작동하지 않는다는 것을 발견했습니다. 그래서 이제는 어떤 dublicates도 생성되고 있음을 무효화하려고합니다! 그러나 문제가 있습니다!

내 목록을 반복해서 살펴보고 개체가 이미 만들어 졌는지 여부를 확인할 수 없습니다.

while (query.next()) { 
    if (!queues.isEmpty()) { 
     /*This gives the Execption->*/ 
     for (CallQueue callQueue : queues) { 
      if (callQueue.getType().equals(query.getString("KØ"))) { 
       double decimalTime = query.getDouble("TID"); 
       int hourOfDay = (int)Math.round(24 * decimalTime); 
       int callAmount = query.getInteger("ANTAL_KALD"); 
       if (hourOfDay > 19) { 
        hourOfDay = 19; 
       } 
       callQueue.addCallsByTime(hourOfDay, callAmount); 
      } else { 
       String queueName = query.getString("Kø"); 
       if (!queueName.equalsIgnoreCase("PrivatOverflow")) { 
        CallQueue cq = new CallQueue(query.getString("KØ")); 
        double decimalTime = query.getDouble("TID"); 
        int hourOfDay = (int)Math.round(24 * decimalTime); 
        int callAmount = query.getInteger("ANTAL_KALD"); 
        if (hourOfDay > 19) { 
         hourOfDay = 19; 
        } 
        cq.addCallsByTime(hourOfDay, callAmount); 
        queues.add(cq); 
       } 
      } 
     } 
    } else { 
     String queueName = query.getString("Kø"); 
     if (!queueName.equalsIgnoreCase("PrivatOverflow")) { 
      CallQueue cq = new CallQueue(query.getString("KØ")); 
      double decimalTime = query.getDouble("TID"); 
      int hourOfDay = (int)Math.round(24 * decimalTime); 
      int callAmount = query.getInteger("ANTAL_KALD"); 
      if (hourOfDay > 19) { 
       hourOfDay = 19; 
      } 
      cq.addCallsByTime(hourOfDay, callAmount); 
      queues.add(cq); 
     } 
    } 
} 

for (CallQueue callQueue : queues) { 
    System.out.println(callQueue.getType()); 
} 
query.Close(); 
return queues; 

내가이에서 얻는 execption은 다음과 같습니다 :

Caused by: java.util.ConcurrentModificationException 

필자 ConcurrentModificationException 에서 execption을 올려 보았습니다

이 사람이 나에게이 문제를 해결하는 데 도움을 줄 수 있습니다 여기에

내 코드입니다 문제?

+2

전체 스택 추적을 게시하십시오. –

+0

제 조언 : iterating하는 동안 항목을 추가하려는 경우 for-each 구문을 사용하는 대신 인덱스를 통해 반복하십시오. – Eric

+0

아마 당신은이 루프를 만들기 위해 synchronized 블록을 사용할 수 있습니다. – matheuslf

답변

5

반복의 내부를 추가하고 있습니다. 사양에 따라 반복되는 컬렉션을 수정할 수 없습니다.

고전적인 솔루션은 컬렉션의 사본을 먼저 만들고 그 대신에 반복하는 것입니다. 또 다른 해결책은 반복자 (짧은 foreach 표기법은 암시 적으로 그것을 사용하고 있음)를 사용하지 않고 수동으로 색인을 사용하여 반복하는 것입니다.

더 나은 해결책은 목록 대신 집합을 사용하는 것입니다 (순서가 중요하지 않은 경우). 즉, equals 및 hashcode를 올바르게 구현해야한다는 의미입니다.

Btw : 귀하의 코드에 결함이있는 것 같습니다. 당신은 당신의 목록을 반복하고 있으며, 만나는 항목이 일치하지 않으면 끝에 하나를 추가합니다. 즉, 찾고있는 항목이 목록의 x 번째 항목 인 경우 새 항목을 x 번 추가하게됩니다. 나는 그것이 당신이 필요로하는 것임을 진지하게 의심합니다. 리팩토링을하면 즉시 해결됩니다.

+0

@Marc 여러분은 CopyOnWriteArrayList도 사용할 수 있으며이 복사 기능을 통합합니다. –

+0

@Joeri 먼저 답장을 보내 주셔서 감사합니다. 내 코드에 결함이 있다는 것에 대한 귀하의 의견은 당신이 abit을 정교하게 만들 수 있습니까? 어떻게 내가 다른 사람들을 데려다주지 않을 것인가? –

+0

@MarcRasmussen 기본적으로 요소를 찾았는지 여부를 확인하는 작업은 반복 작업의 _outside_ 일 필요가 있습니다. 가장 좋은 방법은 찾기 로직을 ​​자체 메소드로 리팩터링하는 것입니다. 그렇게하면 빈 목록을 확인하기 위해 지금 가지고있는 코드의 중복을 제거 할 수 있습니다. findQueue가 null를 돌려주는 경우,리스트가 하늘인지 아닌지에 관계없이 새로운 것을 작성해 추가 할 필요가 있습니다. –