상황
주어진 문자열로 재귀적인 방법을 사용해서 집합을 만들기 위해서 다음과 같은 코드를 작성하였다.
public ArrayList<String> makeSet(ArrayList<String> prev, String firstStr, String subStr){
ArrayList<String> result = new ArrayList<>();
if(subStr.equals("")){
result.add("");
result.add(firstStr);
return result;
}
prev = makeSet(prev, String.valueOf(subStr.charAt(0)), subStr.substring(1));
result = prev;
for(String s : result){
result.add(firstStr+s);
}
Collections.sort(result);
return result;
}
firstStr를 제외한 subStr로 만들어진 집합을 ArrayList<String> prev로 할당받고, result에 기존 집합(prev)를 할당하고, result를 순회하면서 firstStr를 추가한 String을 추가하였는데 다음과 같이 ConcurrentModificationException이 발생하였다.
에러코드
원인
이 에러는 허용되지 않았을 때 동시적으로 object를 수정하려고 시도할 때 발생한다고 하며 주로 Java Collection Classes 객체를 순회하면서 요소를 삭제하거나 변경을 할 때 발생한다.
예를 들어, 다음과 같이 list를 순회하면서 value가 3인 값이 있으면 list에서 해당 value를 삭제하는 코드이다.
public class Concurrentmodificationexception {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
Integer value = it.next();
System.out.println("List Value:" + value);
if (value.equals(3))
list.remove(value);
}
}
}
iterator로 list를 순회하면서 우리는 이것을 동시적으로 수정하려고 했기 때문에 발생하는 문제이다. Index가 변경되어 일부 요소는 순회하지 않을 수 있다. List에서 문제가 발생할 수 있는 것을 감지하여 ConcurrentModificationException를 발생시킨다.
해결방안
public ArrayList<String> makeSet(ArrayList<String> prev, String firstStr, String subStr){
System.out.println("firstStr = " + firstStr);
System.out.println("subStr = " + subStr);
ArrayList<String> result = new ArrayList<>();
if(subStr.equals("")){
result.add("");
result.add(firstStr);
return result;
}
prev = makeSet(prev, String.valueOf(subStr.charAt(0)), subStr.substring(1));
for(String s : prev){
result.add(s);
result.add(firstStr+s);
}
Collections.sort(result);
return result;
}
다음과 같이 prev를 순회하면서 추가는 result에 하도록 코드를 작성했다.
혹은 크기가 변하지 않는 배열을 사용하거나 synchronize 키워드를 사용하는 방법도 있다.
'Language > Java' 카테고리의 다른 글
[Java] Map 인터페이스 (0) | 2023.05.15 |
---|---|
[Java] Collection 프레임워크 (0) | 2023.05.15 |
[Java] Object 클래스 메소드 - toString() (0) | 2022.11.07 |
[Java] Object 클래스 (0) | 2022.11.07 |
[Java] 기타 제어자 (0) | 2022.11.07 |