•
자바 8에서는 List와 Set 인터페이스에 다음과 같은 메서드가 추가됐다.
◦
removeIf
▪
프레디케이트를 인수로 받아 해당 프레디케이트를 만족하는 요소를 제거한다. List나 Set을 구현, 상속받은 모든 클래스에서 사용 가능하다.
◦
replaceAll
▪
리스트에서 이용할 수 있는 기능으로 UnaryOperator를 인수로 받아 요소를 바꾼다.
◦
sort
▪
List 인터페이스에서 제공하는 기능으로 Comparator를 인수로 받아 리스트를 정렬한다.
•
이들 메서드는 새로운 결과를 만드는 스트림 동작과 달리 기존 컬렉션을 변경하는 메서드다.
•
이런 메서드가 추가된 이유로 컬렉션을 바꾸는 동작은 에러를 유발하며 복잡함을 증가시키기 때문이다.
1. removeIf 메서드
for (Transaction transaction : transcations) {
if (Character.isDigit(transaction.getRefrenceCode().charAt(0))) {
transactions.remove(transaction);
}
}
Java
복사
•
위 코드는 ConcurrentModificationException을 일으킨다. 왜일까?
•
먼저 위의 for-each 루프는 Iterator 객체를 사용하므로 다음과 같이 표현되는데
for (Iterator<Transaction> iterator = transcations.iterator(); iterator.hasNext();) {
Transaction transcation = iterator.next();
if (Character.isDigit(transaction.getRefrenceCode().charAt(0))) {
transcations.remove(transaction);
}
}
Java
복사
◦
뭐가 문제인지 이제 좀 보일것이다.
◦
먼저 우리는 iterator를 통해 반복을 수행한다. 즉 다음에 처리할 소스를 질의하는 것이다.
◦
정작 remove()를 호출해 요소를 삭제하는 연산은 Collection 객체에서 처리하고 있다.
◦
결과적으로 반복자의 상태가 컬렉션의 상태와 서로 동기화되지 않아 발생하는 문제다.
•
이는 Iterator 객체를 명시적으로 사용하고 그 객체의 remove() 메서드를 호출함으로써 다음과 같이 해결가능하다.
for (Iterator<Transaction> iterator = transcations.iterator(); iterator.hasNext();) {
Transaction transcation = iterator.next();
if (Character.isDigit(transaction.getRefrenceCode().charAt(0))) {
iterator.remove();
}
}
Java
복사
•
이는 코드의 복잡함을 야기한다 때문에 removeIf가 추가된 것이다. 그러면 코드가 단순해질 뿐만 아니라 버그도 예방할 수 있다.
transactions.removeIf(transaction -> Character.isDigit(trnascation.getReferenceCode().charAt(0)));
Java
복사
◦
개쩔죠?
2. replaceAll 메서드
•
스트림 API를 사용하면 우리는 리스트의 각 요소에 변경작업을 수행할 수 있었다.
referenceCodes.stream().map(code -> Character.toUpperCase(code.charAt(0)) + code.substring(1)).collect(Collectors.toList());
Java
복사
•
하지만 이 코드는 새 문자열 컬렉션을 만든다. 만약 우리가 기존 컬렉션을 변경하는 것을 원한다면 다음과 같으 ListIterator 객체를 사용할 수 있다.
for (ListIterator<String> iterator = referenceCodes.listIterator(); iterator.hasNext(); ) {
String code = iterator.next();
iterator.set(Character.toUpperCase(code.charAt(0)) + code.substring(1));
}
Java
복사
•
또 코드가 복잡해졌다. 여기서 우리는 replaceAll을 사용할 수 있다.
referenceCOdes.replaceAll(code -> Character.toUpperCase(code.charAt(0)) + code.substring(1));
Java
복사
◦
쩔죠?
3. sort 메서드
•
책에서도 설명을 안 한다.
•
Compartor를 인수로 넘겨주면 이에 해당하는 정렬된 상태가 나오지 않을까