Kotlin

코틀린 Kotlin java.util.ConcurrentModificationException 에러

노루룽 2024. 7. 11. 19:55

그렇다.

 

이 글은 방금 코테에서 저 에러를 보고 처음 보는 에러라 당황했고,

로직은 다 짰는데 저것 때문에 문제를 못 풀어서 분노에 차서 쓰는 글이다.

 

 java.util.ConcurrentModificationException 이란^^!!

주로 리스트를 순회하면서 동시에 수정할 때 발생하는 에러이다.

 

나같은 경우에 list를 for문으로 돌리면서, 

tempList = list를 선언했는데,

이것이 문제였다..😵

 

이해가 쉽도록 코드를 보자!

 

list 맨 앞의 element를 맨뒤로 옮기는 작업을 반복하는 로직이다.

fun solution(list: MutableList<Int>) {
    for ((i, element) in list.withIndex()) {
        val tempList = list
        val firstElement = tempList.removeAt(0)
        tempList.add(firstElement)
    }
}

 

3번째 줄을 보아라 . .

멍청한 나 . . 🤦‍♀️

 

저렇게 선언하면 tempList도 list와 같은 곳을 가리키므로

for문으로 list를 순회하는 건 tempList를 순회하는 거나 마찬가지가 된다.

 

그래서 ConcurrentModificationException이 발생했던 것이다.

 

이를 해결할 몇 가지 방법들이 있다.

 

1. 임시 리스트 선언

fun solution(list: MutableList<Int>) {
    for ((i, element) in list.withIndex()) {
        val tempList = mutableListOf(list) // mutableList를 새로 선언
        val firstElement = tempList.removeAt(0)
        tempList.add(firstElement)
    }
}

 

내가 해결한 방법이다.!

내용물(?)은 똑같지만 다른 collection을 선언해 주는 것이다.

 

 

2. indices 사용

fun solution(list: MutableList<Int>) {
    for (i in list.indices) {
        val firstElement = list.removeAt(0)
        list.add(firstElement)
    }
}

 

만약 list의 element가 필요 없다면, 이 방법이 효율적이다.

 

indices 함수의 내부를 살펴보면 다음과 같다.

public val Collection<*>.indices: IntRange
    get() = 0..size - 1

 

즉, list의 인덱스(IntRange)로 접근하는 것이기 때문에 직접 list를 순회하는 것이 아니므로

ConcurrentModificationException이 발생하지 않는다.

 

 

 

list의 element가 필요할 땐 1번 방법을

아니면 2번 방법을 쓰면 될 것 같다.

 

🥹