Java8 stream 특정 key 중복제거

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]

Written by

엘디는 사랑입니다.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store