반복하고 싶은 ArrayList가 있습니다. 그것을 반복하면서 동시에 요소를 제거해야합니다. 분명히 이것은을 던집니다 java.util.ConcurrentModificationException
.
이 문제를 처리하는 가장 좋은 방법은 무엇입니까? 먼저 목록을 복제해야합니까?
루프 자체가 아닌 코드의 다른 부분에서 요소를 제거합니다.
내 코드는 다음과 같습니다
public class Test() {
private ArrayList<A> abc = new ArrayList<A>();
public void doStuff() {
for (A a : abc)
a.doSomething();
}
public void removeA(A a) {
abc.remove(a);
}
}
a.doSomething
호출 할 수 있습니다 Test.removeA()
;
답변
두 가지 옵션 :
- 루프 내에서 해당 목록에 추가 하여 제거하려는 값 목록을 작성한 다음
originalList.removeAll(valuesToRemove)
끝에서 호출 하십시오. remove()
반복자 자체 에서 메소드를 사용하십시오 . 이는 향상된 for 루프를 사용할 수 없음을 의미합니다.
두 번째 옵션의 예로, 목록에서 길이가 5보다 큰 문자열을 제거하십시오.
List<String> list = new ArrayList<String>();
...
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
String value = iterator.next();
if (value.length() > 5) {
iterator.remove();
}
}
답변
ArrayList의 JavaDoc에서
이 클래스의 이터레이터와 listIterator 메소드에 의해 리턴 된 이터레이터는 빠르다 : 이터레이터가 작성된 후 언제라도리스트가 구조적으로 수정 되면, 이터레이터 자신의 remove 또는 add 메소드를 제외하고 어떤 식 으로든 이터레이터는 ConcurrentModificationException을 발생시킨다.
답변
고급 “for loop”의 목록에서 값을 제거하려고합니다. 코드에서 수행 한 트릭을 적용하더라도 불가능합니다. 더 좋은 방법은 다른 조언과 같이 반복자 수준을 코딩하는 것입니다.
사람들이 전통적인 for 루프 접근법을 어떻게 제안하지 않았는지 궁금합니다.
for( int i = 0; i < lStringList.size(); i++ )
{
String lValue = lStringList.get( i );
if(lValue.equals("_Not_Required"))
{
lStringList.remove(lValue);
i--;
}
}
이것은 잘 작동합니다.
답변
전통적인 방식으로 배열을 반복해야합니다.
목록에서 요소를 제거 할 때마다 이후의 요소가 푸시됩니다. 반복 요소 이외의 요소를 변경하지 않는 한 다음 코드가 작동합니다.
public class Test(){
private ArrayList<A> abc = new ArrayList<A>();
public void doStuff(){
for(int i = (abc.size() - 1); i >= 0; i--)
abc.get(i).doSomething();
}
public void removeA(A a){
abc.remove(a);
}
}
답변
Java 8에서는 Collection Interface를 사용하고 removeIf 메소드를 호출하여이를 수행 할 수 있습니다.
yourList.removeIf((A a) -> a.value == 2);
자세한 내용은 여기를 참조하십시오
답변
정상적인 방법으로 루프를 수행하십시오 java.util.ConcurrentModificationException
. 액세스되는 요소와 관련된 오류입니다.
그래서 시도하십시오 :
for(int i = 0; i < list.size(); i++){
lista.get(i).action();
}
답변
목록을 반복하는 동안 요소를 제거하려는 경우 가능합니다. 내 예를 아래에서 보자.
ArrayList<String> names = new ArrayList<String>();
names.add("abc");
names.add("def");
names.add("ghi");
names.add("xyz");
위의 배열 목록 이름이 있습니다. 그리고 위 목록에서 “def”이름을 제거하고 싶습니다.
for(String name : names){
if(name.equals("def")){
names.remove("def");
}
}
위의 코드는 ConcurrentModificationException을 발생 시킵니다.반복하는 동안 목록을 수정하기 때문에 예외를 발생시킵니다.
이런 식으로 Arraylist에서 “def”이름을 제거하려면
Iterator<String> itr = names.iterator();
while(itr.hasNext()){
String name = itr.next();
if(name.equals("def")){
itr.remove();
}
}
위 코드는 반복자를 통해 Arraylist에서 “def”이름을 제거하고 배열을 인쇄하려고하면 아래 출력을 볼 수 있습니다.
출력 : [abc, ghi, xyz]