2014-07-11 3 views
1

각 루프에 대해 Set 유형이 있습니다.집합과 ConcurrentModificationException

이 세트를 반복하면서 요소를 추가합니다.

for (Object o: Set) { 
    //i do something and add to the set 
    } 

나는 계속 ConcurrentModificationException을 얻습니다. 그러나 나는이 예외를 발생시키지 않을이 Set에 어떻게 추가 할 것인지 모른다. 나는 작동하지 않을 각 루프에 대해 새로운 것을 생성 할 수 없다.

누구나 올바른 방향으로 나를 가리킬 수 있습니까?

+1

@RuchiraGayanRanaweera : 반복자는 값의 제거 *를 허용하지만 * 추가 ​​*는 허용하지 않습니다. –

+0

"작동하지 않는 각 루프에 대해 새로운 것을 만들 수 없다"는 것은 무엇을 의미합니까? 정확히 작동하지 않는 것은 무엇이며 어떤 방식으로 작동하지 않을까요? 나는 보통 "나중에 추가 할 것들"의 모음을 만들고 나중에 추가 할 것입니다. –

+0

내 말은 정확히 동일한 세트를 사용하고 지속적으로 업데이트해야한다는 것입니다. 그러나 나는 그것을하는 방법을 알아낼 것 같지 않은가? –

답변

2

당신은, 예를 들어 ConcurrentModifcationException을 유발하지 않는 중 하나

  • Set를 사용해야 ConcurrentXxxSet
  • 집합을 변경하기 전에 복사본을 가져옵니다.

간단한 변화는 제네릭

for (Object o: set.toArray()) { 
    if (condition(o)) 
     set.add(something); 
} 

이 간단한 해결책이

Set<T> set = 
for(T t: new HashSet<T>(set)) { 
    // something which might add to set 
} 

참고 될 수있다 :이 방금 추가 한 요소의 반복을 방지 할 수 있습니다. 주 2 : 동시 세트를 사용하면 추가 된 요소가 표시되거나 가능하지 않을 수 있습니다.

요소를 추가 할 때 요소를 실제로 볼 필요가있는 경우 목록을 사용하거나 대신 해당 요소를 사용해야합니다.

List<T> list = new ArrayList<>(set); 

for(int i = 0; i < list.size(); i++) { 
    T t = list.get(i); 

    if (condition) 
     // if it is not a duplicate 
     if (set.add(something)) 
      list.add(something); 
} 

이렇게하면 신뢰할 수있는 방식으로 루프에 추가 한 요소를 볼 수 있습니다. 참고 : 무한 루프를 만들지 않고 메모리를 모두 사용하지 않도록주의를 기울여야합니다.

대신 목록 대신 대기열을 사용하는 방법도 있습니다. 이것은 더 좋을 수도 있지만 덜 효율적이라고 생각합니다.

Queue<T> q = new ConcurrentLinkedQueue<>(set); 

for(T t : q) { 
    if (condition) 
     // if it is not a duplicate 
     if (set.add(something)) 
      q.add(something); 
} 
+0

대기열의 효율성이 얼마나 떨어 집니까? 나는 많은 양의 데이터를 다루고 있으므로 Set을 사용하고자하는 이유는 무엇입니까? –

0

당신은 임시 Set을이 임시 세트에 요소를 추가, 당신은 모든 요소를 ​​통해 전지 완료되면, 원래의 설정

예로 설정 임시의 값을 추가 할 수 있습니다

Set<Integer> originalSet; 
//stuff where you fill your original Set 
Set<Integer> tempSet = new Set<Integer>(); 

for(Integer i : originalSet) { 
    tempSet.add(<integerToAdd>); 
} 
originalSet.addAll(tempSet); 
+0

그러나 originalSet을 루핑하는 방법은 무엇입니까? 나는 그것을 멈추고 싶지 않다. –

+0

루핑을 계속한다는 것은 무엇을 의미 하는가? originalSet에있는 모든 항목을 계속 반복합니다. 또는 tempList에 추가하는 항목을 반복해야합니까? – bvanvelsen

+0

예. 임시 목록의 항목도 반복해야하며 더 이상 항목이 추가되지 않을 때까지 계속 진행해야합니까? Arraylists와 함께 작동하여 세트로 작동하도록하십시오. –

관련 문제