프론트엔드
ArrayList.remove() 사용시 주의점
디지털노마더
2020. 7. 7. 22:02
ArrayList 데이터에서 특정 조건에 해당하는 값을 모두 삭제하는 함수를 생성하여 테스트 하는 과정에서
IndexOutOfException 에러가 발생했다.
아래는 문제의 소스코드이다. 여러분들은 딱 보았을 때 어느 부분이 문제점인지 바로 보이시나요?
ArrayList<String> wishList = new ArrayList<String>(Arrays.asList("android", "java", "ios", "kotlin"));
for(int idx=0; idx<wishList.size(); idx++) {
if(wishList.get(idx).equals("ios") {
wishList.remove(idx);
}
}
원인이 무엇인고 확인해보니, ArrayList.remove()시 ArrayList.size()값이 하나씩 줄어드는데
반복문 조건에서 삭제하기 이전의 갯수만큼 실행되다보니 존재하지 않는 Index를 호출하여 에러가 발생하는 것이다.
문제가 발생하는 요인은 idx(인덱스) 변수 데이터이다. 왜냐하면 "ios"가 위치한 idx=2에서 삭제가 이루어지면
wishList.size() 값은 3이 될것이다.
하지만, 우리가 반복문을 실행할 초기에는 wishList.size() = 4 이었기 때문에 wishList.get(3).equals("ios")를 시도한다.
그래서 존재하지 않는 인덱스(3)에 접근해서 IndexOutOfException이 발생한다.
위의 상황을 개선하고자 생각했던 1차 방법이 아래의 소스코드.
ArrayList<String> wishList = new ArrayList<String>(Arrays.asList("android", "java", "ios", "kotlin"));
ArrayList<String> tempList = new ArrayList<String>(); // 임시변수 사용
for(int idx=0; idx<wishList.size(); idx++) {
String item = wishList.get(idx);
if(!item.equals("ios") {
tempList.add(item);
}
}
wishList = tempList;
wishList에서 조건에 해당하지 않는 데이터만 임시변수에 새로 추가하여 wishList에 tempList 데이를 대체하는 방식으로 'IndexOutOfException' 에러를 보완하였다.
하지만 베스트의 대안은 아니다. 아래는 최종적으로 Iterator를 이용하여 보다 직관적이고 간편한 방법이다.
ArrayList<String> list = new ArrayList<String>(Arrays.asList("android", "java", "ios", "kotlin"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
String s = iter.next();
if (s.equals("ios")) {
iter.remove();
}
}