Programing

ArrayList에 대한 ConcurrentModificationException

lottogame 2020. 10. 9. 08:44
반응형

ArrayList에 대한 ConcurrentModificationException


다음 코드가 있습니다.

private String toString(List<DrugStrength> aDrugStrengthList) {
    StringBuilder str = new StringBuilder();
        for (DrugStrength aDrugStrength : aDrugStrengthList) {
            if (!aDrugStrength.isValidDrugDescription()) {
                aDrugStrengthList.remove(aDrugStrength);
            }
        }
        str.append(aDrugStrengthList);
        if (str.indexOf("]") != -1) {
            str.insert(str.lastIndexOf("]"), "\n          " );
        }
    return str.toString();
}

실행하려고 할 때 ConcurrentModificationException코드가 동일한 스레드에서 실행되는 경우에도 왜 발생하는지 설명 할 수 있습니까? 그리고 어떻게 피할 수 있습니까?


"for each"루프를 사용하여 검색하는 경우 목록에서 제거 할 수 없습니다. 사용할 수 있습니다 Iterator. 바꾸다:

for (DrugStrength aDrugStrength : aDrugStrengthList) {
    if (!aDrugStrength.isValidDrugDescription()) {
        aDrugStrengthList.remove(aDrugStrength);
    }
}

와:

for (Iterator<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
    DrugStrength aDrugStrength = it.next();
    if (!aDrugStrength.isValidDrugDescription()) {
        it.remove();
    }
}

다른 답변과 마찬가지로 반복중인 컬렉션에서 항목을 제거 할 수 없습니다. 명시 적으로를 사용 Iterator하고 항목을 제거 하여이 문제를 해결할 수 있습니다 .

Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
  Item blah = iter.next();
  if(...) {
    iter.remove(); // Removes the 'current' item
  }
}

나는 다음과 같은 루프의 역순을 좋아합니다.

int size = list.size();
for (int i = size - 1; i >= 0; i--) {
    if(remove){
        list.remove(i);
    }
}

새로운 데이터 구조 나 클래스를 배울 필요가 없기 때문입니다.


이러한 작업을 지원하는 List 인터페이스의 동시 구현이 있어야합니다.

java.util.concurrent.CopyOnWriteArrayList.class 시도


루프를 반복하는 동안 remove () 작업에서 List 값을 변경하려고합니다. 이로 인해 ConcurrentModificationException이 발생합니다.

아래 코드를 따르면 원하는 것을 얻을 수 있지만 예외는 발생하지 않습니다.

private String toString(List aDrugStrengthList) {
        StringBuilder str = new StringBuilder();
    List removalList = new ArrayList();
    for (DrugStrength aDrugStrength : aDrugStrengthList) {
        if (!aDrugStrength.isValidDrugDescription()) {
            removalList.add(aDrugStrength);
        }
    }
    aDrugStrengthList.removeAll(removalList);
    str.append(aDrugStrengthList);
    if (str.indexOf("]") != -1) {
        str.insert(str.lastIndexOf("]"), "\n          " );
    }
    return str.toString();
}

동시 컬렉션 클래스를 사용하여 컬렉션을 반복하는 동안 ConcurrentModificationException을 방지 할 수 있습니다 (예 : ArrayList 대신 CopyOnWriteArrayList).

이 게시물에서 ConcurrentHashMap 확인

http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator

참고URL : https://stackoverflow.com/questions/3184883/concurrentmodificationexception-for-arraylist

반응형