java8 의 Collection 객체의 stream에서 중복제거를 할때.
distinct()를 보통 사용한다.
Stream<T> 의 T타입 객체의 인스턴스만을 중복키로 사용하여 제거한다.
때문에 T타입 객체내의 특정 키를 기준으로 중복제거를 할수는 없다.
stackOverflow에는 아래와 같은 해법이 있다.
public static <T> Predicate<T> distinctByKey( Function<? super T, Object> keyExtractor) {Map<Object, Boolean> map = new ConcurrentHashMap<>();return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
Predicate 를 리턴하는 distinctByKey 라는 메소드는 메소드의 지역변수로
HashMap을 생성하고 리턴하는 Predicate 에서는 Map을 참조하고 있다.(javascript의 closure 같다.)
또한 중복체크할 키를 생성하는 Function 을 인자로 받고 있다.
- ConcurrentHashMap으로 된 이유가 있나? 했을때 생각난 부부은
parallelStream 의 경우 때문이라고 생각됨. - stream일 경우는 HashMap으로 해도 되겠다는 생각.
- 메소드를 통해 생성된 Predicate 객체는 생성될때마다 개별 Map을 가진다.
- 람다식이 컴파일 될때는 , Map 과 Function을 인자로 받는 람다 메소드가 생성되겟다.
* 아래는 sample 이다.
멤버리스트를 생성하고 일부 같은 나이를 가지는 멤버를 담았다.
결과는
Member [name=unknown_10, age=10]
Member [name=unknown_11, age=11]
Member [name=unknown_12, age=12]
Member [name=aa13, age=13]
Member [name=aa14, age=14]
Member [name=aa15, age=15]
Member [name=aa16, age=16]
Member [name=unknown_17, age=17]
Member [name=unknown_18, age=18]
Member [name=unknown_19, age=19]