개발관련/오류노트
컬렉션을 반복하여 루프에서 개체를 제거 할 때 ConcurrentModificationException 방지
Rateye
2021. 6. 9. 10:18
728x90
반응형
질문 : 컬렉션을 반복하여 루프에서 개체를 제거 할 때 ConcurrentModificationException 방지
ConcurrentModificationException
때문에 다음을 수행 할 수 없다는 것을 모두 알고 있습니다.
for (Object i : l) {
if (condition(i)) {
l.remove(i);
}
}
그러나 이것은 분명히 때때로 작동하지만 항상 그런 것은 아닙니다. 다음은 몇 가지 특정 코드입니다.
public static void main(String[] args) {
Collection<Integer> l = new ArrayList<>();
for (int i = 0; i < 10; ++i) {
l.add(4);
l.add(5);
l.add(6);
}
for (int i : l) {
if (i == 5) {
l.remove(i);
}
}
System.out.println(l);
}
물론 결과는 다음과 같습니다.
Exception in thread "main" java.util.ConcurrentModificationException
여러 스레드가 수행하지 않더라도. 어쨌든.
이 문제에 대한 최선의 해결책은 무엇입니까? 이 예외를 발생시키지 않고 루프에서 컬렉션에서 항목을 제거하려면 어떻게해야합니까?
여기서도 ArrayList
아닌 임의의 Collection
get
의존 할 수 없습니다.
답변
Iterator.remove()
는 안전하며 다음과 같이 사용할 수 있습니다.
List<String> list = new ArrayList<>();
// This is a clever way to create the iterator and call iterator.hasNext() like
// you would do in a while-loop. It would be the same as doing:
// Iterator<String> iterator = list.iterator();
// while (iterator.hasNext()) {
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
// Remove the current element from the iterator and the list.
iterator.remove();
}
}
Iterator.remove()
는 반복 중에 컬렉션을 수정하는 유일한 안전한 방법입니다. 반복이 진행되는 동안 기본 컬렉션이 다른 방식으로 수정되면 동작이 지정되지 않습니다.
마찬가지로 ListIterator
있고 항목을 추가 ListIterator#add
사용할 수 있습니다. 같은 이유로 Iterator#remove
를 사용할 수 있습니다. 허용하도록 설계되었습니다.
귀하의 경우 목록에서 제거하려고했지만 콘텐츠를 반복하는 동안 Map
put
출처 : https://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re
728x90
반응형