'동시 수정'을 회피하는 방법'ArrayList'를 반복하는 동안 요소를 제거하는 동안 예외"를 선택하십시오.
난 지금 몇 가지 요소를 제거하려고 하고 있어ArrayList
이렇게 반복하면서.
for (String str : myArrayList) {
if (someCondition) {
myArrayList.remove(str);
}
}
물론, 나는 그것을 받는다.ConcurrentModificationException
반복할 때 목록에서 항목을 동시에 제거하려고 할 때myArrayList
이 문제를 해결할 수 있는 간단한 방법이 있습니까?
및 콜을 사용합니다.
Iterator<String> iter = myArrayList.iterator();
while (iter.hasNext()) {
String str = iter.next();
if (someCondition)
iter.remove();
}
다른 사람들의 대답 대신 저는 항상 다음과 같은 일을 해왔습니다.
List<String> toRemove = new ArrayList<String>();
for (String str : myArrayList) {
if (someCondition) {
toRemove.add(str);
}
}
myArrayList.removeAll(toRemove);
이렇게 하면 반복기를 직접 처리할 필요가 없지만 다른 목록이 필요합니다.이유야 어떻든 난 항상 이 길을 선호해왔어.
Java 8 사용자는 다음을 수행할 수 있습니다.list.removeIf(...)
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
list.removeIf(e -> (someCondition));
someCondition이 충족되는 목록에서 요소를 제거합니다.
반복기의 remove() 메서드를 사용해야 합니다.즉, 루프는 확장되지 않습니다.
for (final Iterator iterator = myArrayList.iterator(); iterator.hasNext(); ) {
iterator.next();
if (someCondition) {
iterator.remove();
}
}
아뇨, 아뇨!
단일 처리 태스크에서는 Iterator를 사용할 필요가 없습니다.또한 CopyOnWriteArrayList(퍼포먼스 저하로 인해)를 사용할 필요가 없습니다.
해결 방법은 훨씬 간단합니다. 각 루프를 위한 것이 아니라 루프를 위한 규범적인 방법을 사용해 보십시오.
Java의 각 루프 가이드에 대한 저작권 소유자(몇 년 전 Sun, 현재는 Oracle)에 따르면, 이 가이드는 반복기를 사용하여 컬렉션을 살펴보고 코드를 더 보기 좋게 숨깁니다.그러나 유감스럽게도 수익보다 문제가 더 많이 발생했고, 그렇지 않으면 이 주제는 나오지 않을 것입니다.
예를 들어 이 코드는 java.util로 이어집니다.동시 수정수정된 ArrayList에 다음 반복을 입력할 때 예외:
// process collection
for (SomeClass currElement: testList) {
SomeClass founDuplicate = findDuplicates(currElement);
if (founDuplicate != null) {
uniqueTestList.add(founDuplicate);
testList.remove(testList.indexOf(currElement));
}
}
다만, 다음의 코드는 정상적으로 동작합니다.
// process collection
for (int i = 0; i < testList.size(); i++) {
SomeClass currElement = testList.get(i);
SomeClass founDuplicate = findDuplicates(currElement);
if (founDuplicate != null) {
uniqueTestList.add(founDuplicate);
testList.remove(testList.indexOf(currElement));
i--; //to avoid skipping of shifted element
}
}
따라서 수집을 반복할 때는 인덱싱 방식을 사용하고 각 루프는 동일하지 않으므로 피하십시오.For-각 루프는 수집 변경을 체크하고 Concurrent Modification을 슬로우하는 일부 내부 반복기를 사용합니다.예외입니다.이것을 확인하려면 , 내가 투고하고 있는 최초의 예를 사용하고, 인쇄된 스택 트레이스를 자세하게 봐 주세요.
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at TestFail.main(TestFail.java:43)
멀티스레딩의 경우 대응하는 멀티태스킹접근법(synchronized 키워드 등)을 사용합니다.
권장되는 다른 솔루션은 기능하지만 솔루션을 스레드 세이프하게 하려면 ArrayList를 CopyOnWriteArrayList로 대체해야 합니다.
//List<String> s = new ArrayList<>(); //Will throw exception
List<String> s = new CopyOnWriteArrayList<>();
s.add("B");
Iterator<String> it = s.iterator();
s.add("A");
//Below removes only "B" from List
while (it.hasNext()) {
s.remove(it.next());
}
System.out.println(s);
중에 " " " 를 .Iterator
에 '먹다'를 쓰면 iterator.remove()
트래버설 중에 요소를 제거합니다.
List myArrayList = Collections.synchronizedList(new ArrayList());
//add your elements
myArrayList.add();
myArrayList.add();
myArrayList.add();
synchronized(myArrayList) {
Iterator i = myArrayList.iterator();
while (i.hasNext()){
Object object = i.next();
}
}
다른 으로는 ''을 들 수 있습니다.List
로로 합니다.array
하여 에서 List
당신의 논리에 따라.
List<String> myList = new ArrayList<String>(); // You can use either list or set
myList.add("abc");
myList.add("abcd");
myList.add("abcde");
myList.add("abcdef");
myList.add("abcdefg");
Object[] obj = myList.toArray();
for(Object o:obj) {
if(condition)
myList.remove(o.toString());
}
반복기 remove() 함수를 사용하여 기본 컬렉션 개체에서 개체를 제거할 수 있습니다.그러나 이 경우 목록에서 동일한 개체만 제거할 수 있습니다.
언급URL : https://stackoverflow.com/questions/18448671/how-to-avoid-concurrentmodificationexception-while-removing-elements-from-arr
'programing' 카테고리의 다른 글
문자열에 ASCII만 포함되어 있는지 확인하는 방법 (0) | 2022.09.03 |
---|---|
Javascript DataTransfer 항목이 비동기 호출을 통해 유지되지 않음 (0) | 2022.09.03 |
JMS 및 AMQP - 토끼MQ (0) | 2022.09.03 |
Java의 부울 프리미티브 크기가 정의되지 않은 이유는 무엇입니까? (0) | 2022.09.03 |
JsonParseException : 따옴표가 없는 잘못된 문자(CTRL-CHAR, 코드 10) (0) | 2022.09.03 |