2012-09-27 3 views
4

이미 중첩 된 루프를 통해 반복하면서리스트를 반복하려고합니다. 아래 코드를 고려하십시오.리스트를 통한 중첩 반복 다음에 최종 삭제

ArrayList<Integer> list = new ArrayList<Integer>(); // add some values to it 

for(int i : list) { // ConcurrentModificationException 

    Iterator iterator = list.iterator(); 

    while(iterator.hasNext()) { 

     int n = iterator.next(); 

     if(n % i == 0) { 
     iterator.remove(); 
     } 

    } 

} 

위의 예는 ConcurrentModificationException이 발생합니다. 물론 요소를 제거하기위한 조건은 예제 일뿐입니다.

나는 뭔가를 놓친 것 같다. 하지만 예외를 throw하지 않고 Java에서과 동일한 것을 구현하는 루프를 어떻게 구성해야합니까?

+0

질문 제목에 대한 제안 사항에 매우 만족합니다. – Zar

답변

4

명백히 list을 반복하여 실행하면 반복 실행시 문제가 발생합니다. 다른 목록을 사용하여 제거 할 요소 목록을 유지하고 끝에 제거 할 수 있습니다.

ArrayList<Integer> list = new ArrayList<Integer>(); // add some values to it 
ArrayList<Integer> del = new ArrayList<Integer>(); // Elements to be deleted 

for(int i : list) { // ConcurrentModificationException 
    Iterator iterator = list.iterator(); 
    while(iterator.hasNext()) {  
     int n = iterator.next(); 
     if(n % i == 0) { 
      del.add(n);  
     } 
    } 
} 

list.removeALL(del); 
+0

Err ... 그게'del.add (n)'이 아니어야합니까? – OldCurmudgeon

+0

@OldCurmudgeon 당신이 맞습니다, Ctrl + c, ctrl + v의 죄 : –

+0

이것은 내가 찾고있는 부분입니다. 그러나 while 루프가 완료된 직후에 수행 된 요소를 제거해야합니다. 즉, 각각의 for-cycle의 끝에. – Zar

0

반복중인 목록에서 항목을 제거 할 수 없습니다. 하나의 옵션은 필요한 항목을 다른 목록에 추가하는 것입니다. 마지막으로 필요한 항목 목록이 있습니다. 또는 원래 목록의 복제본을 반복 할 수 있습니다.

1

for 루프를 수행하는 동안 list을 수정하려고하므로 ConcurrentModificationException이 발생합니다.

나는 다음을 작동 할 수 아래처럼 우아한 해결책 또는 아니지만, 뭔가인지 확실하지 않다 :

 Iterator<Integer> iterator = list.iterator(); 
      int i=1; 
      while (iterator.hasNext()) { 

       int n = iterator.next(); 

       if (n % i == 0) { 
        iterator.remove(); 
       } 
       i++; 
      } 
+0

비교를 위해 목록에서 숫자를 사용해야합니다. 따라서, 'i = 1; i ++'는 숫자가 1,2,3 등이 아니기 때문에하지 않을 것입니다. – Zar

+0

반복자를 사용하여리스트에 숫자를 얻었습니까? 그런데 왜 for 루프가 필요한가요? – kosa

+0

저는 Java를 배우지 만 이터레이터는 항목의 (이 경우 목록) 값을 반복하지 않습니까? 목록 값 각각에 대한 루프를 수행해야하는데, 이는 중첩 루프를 사용하도록합니다. – Zar

0

내가 당신에게 매우 유사한 몇 가지 일을. 이 코드를 보면 알 수 있습니다.

out:for(int h=0; h<tempAl.size(); h++) { 
         if(tempAl.get(0).split("\\s")[0].equals("OFF")){ 
          tempAl.remove(0); 
          h=-1; 
          continue; 
         } 
         if(tempAl.get(h).split("\\s")[0].equals("ON")){ 
          ONTime= tempAl.get(h); 
       ///rest fof the code 
    } 

나는 arraylist에서 요소를 제거한 후에도 색인을 변경할 수 있다고 생각합니다.

0

나는 시도하지 않은,하지만 중 하나를 사용 :

List<Integer> list = new ArrayList<Integer>(); 
// add some values to it 
for(Iterator<Integer> iterator1 = list.iterator(); iterator1.hasNext();) { 
    int i = iterator1.next(); 
    for(Iterator<Integer> iterator2 = list.iterator(); iterator2.hasNext();){ 
     int n = iterator.next();   
     if(n % i == 0) {   
      iterator2.remove();  
     }  
    } 
} 

또는이 여전히 ConcurrentModificationException를 (난 당신이 같은리스트를 기본으로 2 반복자를 사용하는 경우 어떻게되는지 확실하지 않다)가 발생하는 경우 다음 사용

List<Integer> list = new ArrayList<Integer>(); 
// add some values to it 
for(int i : new ArrayList(list)){ // copy list 
    ... 
} 
+0

첫 번째 soulution은 여전히 ​​ConcurrentModificationException을 발생시킵니다 .-( – KIC

0

foreach Java 구문 반복자 숨겨져 있지만 숨기고, 이것에 remove 메소드를 호출 할 수 없다.

그래서 내가 할 것이다 :

ArrayList<Integer> list = new ArrayList<Integer>(); // add some values to it 

int count = 0; 
for(Iterator<Integer> it = list.iterator();it.hasNext();count++){ //increments count++ 
    Integer currentInt = it.next(); 
    if(currentInt % count == 0){ 
    it.remove(); 
    } 
} 

는 동일한 기능을 보조 반복자의 필요없이 달성되는 것을 볼 수 있습니다.

동시에 같은 목록을 반복 처리 할 수 ​​없습니다. 요약하면 modcount 변수는 목록이 병렬로 변경되거나 반복 될 때마다 예기치 않은 자체 변경을 감지하는 데 사용됩니다. 따라서 ConcurrentModificationException으로 이어집니다. 멀티 스레드 환경에서는 매우 자주 나타나며 개발자는이를 알고 있어야합니다.

또한 for 루프를 사용하여 컬렉션을 반복하는 루프를 while 회 반복하십시오.

왜?

while 방법을 사용하면 루프 이후에 반복기 개체가 여전히 범위에있는 반면 for 인 경우 반복기 개체는 범위에 포함되지 않습니다. it.next()으로의 간단한 전화는 NoSuchElementException으로 끝납니다.

유지하는 것이 좋습니다

)

2

목록의 사본을 통해 외부 반복으로 반복합니다.

for (int i : new ArrayList<>(list)) { 

    Iterator<Integer> iterator = list.iterator(); 

    while (iterator.hasNext()) { 

    int n = iterator.next(); 

    if (n % i == 0) { 
     iterator.remove(); 
    } 

    } 

}