2012-04-28 2 views
1

나는 아래와 같이 벡터에서 목록을 제거하려고 시도했다.벡터에서 목록 제거 Remove java.util.ConcurrentModificationException

public class StringVectorTest { 

private final List<String> stringVector = new Vector<String>(); 

@Test 
public void listRemoveTest(){ 

    List<String> list = stringVector.subList(0, 2); 

    stringVector.removeAll(list); 

    Assert.assertEquals(stringVector.size(), 3); 
} 

@Before 
public void fillList(){ 
    stringVector.add("ABC"); 
    stringVector.add("DEF"); 
    stringVector.add("GEH"); 
    stringVector.add("IJK"); 
    stringVector.add("LMN"); 
} 

}

난 내가 사람이 나에게 방법을 알려 주시기 바랍니다 수있는이 ConcurrentModificationException을 극복하기 위해 Iterator를 사용한다는 것을 알고 난 아래의 오류

java.util.ConcurrentModificationException 
at java.util.SubList.checkForComodification(AbstractList.java:752) 
at java.util.SubList.listIterator(AbstractList.java:682) 
at java.util.AbstractList.listIterator(AbstractList.java:284) 
at java.util.SubList.iterator(AbstractList.java:678) 
at java.util.AbstractCollection.contains(AbstractCollection.java:82) 
at java.util.Collections$SynchronizedCollection.contains(Collections.java:1563) 
at java.util.AbstractCollection.removeAll(AbstractCollection.java:336) 
at java.util.Vector.removeAll(Vector.java:853) 

을 얻고 테스트를 실행하는 동안 효율적인 방식으로 사용하는 것이 가장 좋습니다. 사전에

감사합니다.

답변

3

아래를 수행

public void listRemoveTest() { 
    stringVector.subList(0, 2).clear(); 
    Assert.assertEquals(stringVector.size(), 3); 
} 
+0

감사 답변을 많이. 그것은 효과가 있었다. – Sam

2

ConcurrentModificationException의 자바 독에서 :

이 예외는, 그러한 변경이 허가되어 있지 않은 경우, 오브젝트의 동시 변경을 검출 한 방법에 의해 발생 될 수있다. 예를 들어, 한 스레드가 다른 스레드가 스레드를 반복하면서 Collection을 수정하는 것은 일반적으로 허용되지 않습니다. 일반적으로 이러한 상황에서는 반복 결과가 정의되지 않습니다. JRE가 제공하는 모든 범용 콜렉션 구현의 구현을 포함 해, 일부의 Iterator 구현은,이 동작이 검출되었을 경우에이 예외를 Throw하도록 선택할 수 있습니다. 이를 수행하는 반복자는 패스트 패스트 반복자으로 알려져 있습니다. 이러한 반복자는 신속하고 명확하게 실패하므로 향후에 예측할 수없는 시간에 임의의 비 결정적 동작을 위험에 빠뜨릴 수 있습니다.

참고이 예외 항상 객체가 동시에 다른 스레드에 의해 수정 된 것으로 표시하지 않습니다. 단일 스레드가 객체의 계약을 위반하는 일련의 메소드 호출을 발행하면 객체는이 예외를 throw 할 수 있습니다. 예를 들어, 패스트 패스트 반복기를 사용하여 컬렉션을 반복하는 동안 스레드가 컬렉션을 직접 수정하는 경우 반복기는이 예외를 throw합니다.

후자는 정확히 무엇을하고 있습니까 (게시 한 스택 추적 참조). subList 메서드는 목록의 보기을 반환하므로이 메서드에서 반환 된 목록은 stringVector에 의해 뒷받침되므로 반환 된 목록의 비 구조적 변경 내용은 stringVector에 반영되며 그 반대의 경우도 마찬가지입니다.

그래서 당신은 요소를 삭제하려면이 "보기"를 사용해야합니다 때문에 반복자와

@Test 
public void listRemoveTestClearingSubList(){ 
    stringVector.subList(0, 2).clear();  
    Assert.assertEquals(stringVector.size(), 3); 
} 

조금 까다과 이보다이다

@Test 
public void listRemoveTestClearingWithIterator(){ 
    Iterator<String> it = stringVector.iterator(); 
    for (int i = 0; i < 2 && it.hasNext(); i++) { 
     it.next(); 
     it.remove(); 
    } 

    Assert.assertEquals(stringVector.size(), 3); 
} 
+0

큰 설명에 감사드립니다. 그것은 작동합니다. :) – Sam