본문 바로가기
Backend/JAVA

[JAVA] List 반복문 안에서 객체 remove (feat.ConcurrentModificationException)

by 지구 2020. 8. 6.

List 를 돌면서 조건에 부합하는 객체는 해당 List 에서 제거를 해줘야 했다.

 

하지만 List(Collection.....😩) 를 루프돌면서 remove 하는 것은 쉽고 간단하지 않았고
( 테스트 도중 빈번하게 ConcurrentModificationException 요 아이와 마주했다;ㅎ)

 

구글링에 나오는 아래 두 가지 방법을 했지만
뭔가.. 소스 읽기도 힘들고 이중으로 돌아서 NPE 아이가 올 때도 있어서 아예 메소드를 리팩토링했다.

1. while(it.hasNext()) {}
2. for (Iterator<객체> it = List<객체>.iterator(); it.hasNext();) {}

 

바로 JAVA8 이상에서만 사용할 수 있는 List.removeIf() !!
https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#removeAll-java.util.Collection-

 

Collection (Java Platform SE 8 )

Compares the specified object with this collection for equality. While the Collection interface adds no stipulations to the general contract for the Object.equals, programmers who implement the Collection interface "directly" (in other words, create a clas

docs.oracle.com

 

오라클 문서를 보면 알겠지만, removeIf() 는 return 이 boolean 이므로
삭제해야 할 조건을 인자로 넣고, 삭제해야 되는 대상인 경우 return true 가 되도록 해주면 된다.

 

가장 simple 한 예제로는 아래가 있으나... 

// 1~6 숫자로 이루어진 integerList 생성
List<Integer> integerList = new ArrayList<>(Arrays.asList(1,2,3,4,5,6));

// integerList 에 짝수 제거
integerList.removeIf(i -> i % 2 == 0);

// print : [1, 3, 5]
System.out.println(integerList);

내 로직은 이렇게 simple 하지 않아서..😓

아래처럼 주절주절 검증로직을 넣어서 isRemove  가 true 가 될 때만 List 에서 제거되도록 리팩토링했다.

객체List.removeIf(객체 -> {
	boolean isRemove = false;
    
    // ~~ 비교객체 검증 ~~ //
    
    if (검증실패) {
    	isRemove = true;
    }
    
    return isRemove;
})

 

결론 !

JAVA8 이상은 .removeIf() 를 적극 사용하자.
.removeIf() 는 복잡한 로직에도 적용할 수 있다!

반응형

댓글