사용자 도구

사이트 도구


java:8:stream

Java 8 Stream

Stream for Iterable

List<List<Object>> 같은 컬렉션의 컬렉션 Flatten

List<List<Object>> list = ...
List<Object> flat = 
    list.stream()
        .flatMap(List::stream)
        .collect(Collectors.toList());

Null safe stream

public static <T> Stream<T> asStream(Collection<T> collection) {
    return Optional.ofNullable(collection)
        .map(Collection::stream)
        .orElse(Stream.empty());
}
 
public static <T> Stream<T> asStream(T[] array) {
    return Optional.ofNullable(array)
        .map(Arrays::stream)
        .orElse(Stream.empty());
}
 
public static <K, V> Stream<Map.Entry<K, V>> asStream(Map<K, V> map) {
    return Optional.ofNullable(map)
        .map(kvMap -> kvMap.entrySet().stream())
        .orElse(Stream.empty());
}

distinct by key

  • 객체의 특정 field / property 를 통해 distinct를 하려면,
  • 별도 Predicate 선언방식
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>(); // parallel stream에서 호출할까봐 이렇게 한듯.
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
     
    persons.stream().filter(distinctByKey(p -> p.getName());
  • toMap이용
    // 특정 Key 필드로 Map을 만들되 중복 값은 모두 무시
    persons.stream()
      .collect(toMap(Person::getName, Function.identity(), (p1, p2) -> p1))
      .values();

parallelStream

  • ``parallelStream``은 작업 분배 오버헤드가 발생하기 때문에 CPU 연산작업만 병렬화 할경우에는 오히려 느려지는 경향이 있다.
  • DB 조회/API 호출 처럼 순차보다는 병렬이 확실히 더 확실할 때 빼고는 parallelStream은 사용하지 않는게 낫다.
  • 그리고 Thread 안정성도 보장해줘야한다.
  • 따라서 성능테스트로 완벽하게 더 좋은 성능이 보장되지 않는다면, 그냥 기본적으로 일반 스트림을 사용해야 한다.

참고

java/8/stream.txt · 마지막으로 수정됨: 2019/10/10 10:20 저자 kwon37xi