기술면접

[Java 기술면접] ConcurrentModificationException 발생

곽코딩루카 2025. 9. 8. 23:05
반응형

이건 자바 면접에서 정말 자주 나오는 ConcurrentModificationException 문제이다.

 

List<String> list = new ArrayList<>(Arrays.asList("a","b","c"));

for (String s : list) {
  if (s.equals("n")) {
    list.remove(s);   // 여기서 문제 !!
  }
}

 

 

1. 왜 오류가 날까?

 

  • for-each 문은 내부적으로 Iterator를 사용해 리스트를 순회합니다.
  • 그런데 순회 도중에 list.remove(s)로 직접 리스트를 수정하면,
    Iterator가 감지 → ConcurrentModificationException 발생.

즉, “Iterator로 순회 중인데, 너 몰래 리스트를 건드렸다”라는 상황이다.

 

2. 안전하게 수정하는 방법

방법 1) Iterator 사용

 

List<String> list = new ArrayList<>(Arrays.asList("a","b","c"));

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("n")) {
        it.remove();   //  안전: Iterator의 remove는 허용
    }
}

 

 

 

방법 2) removeIf (Java 8+)

가장 깔끔하고 요즘 가장 많이 씀 

 

List<String> list = new ArrayList<>(Arrays.asList("a","b","c"));
list.removeIf(s -> s.equals("n"));

 

 

 

방법 3) 새로운 리스트로 필터링

List<String> list = new ArrayList<>(Arrays.asList("a","b","c"));
List<String> filtered = list.stream()
                            .filter(s -> !s.equals("n"))
                            .toList();   // Java 16+에서는 불변 리스트 반환

 

 

 

 

면접 답변 예시

“for-each는 내부적으로 Iterator를 쓰는데, 순회 중에 list.remove()를 호출하면 ConcurrentModificationException이 발생합니다. 안전하게 제거하려면 Iterator의 remove()를 사용하거나, Java 8 이후엔 removeIf 메서드를 쓰는 게 일반적입니다.”

 

 

 

 

반응형