Search
🙉

이펙티브 자바:: 아이템 46 <스트림에서는 부작용 없는 함수를 사용하라>

Intro::

이펙티브 자바 정리본입니다.

결론

스트림 파이프라인 프로그래밍의 핵심은 부작용 없는 함수 객체에 있습니다.
스트림뿐 아니라 스트림 관련 객체에 건네지는 모든 함수 객체가 부작용이 없어야 합니다.
종단 연산 중 forEach는 스트림이 수행한 계산 결과를 보고할 때만 이용해야 합니다. 계산 자체에 이용하지 맙시다.
가장 중요한 수집기 팩터리는 toList, toSet, toMap, groupingBy, joining입니다.

코드 예시

안좋은 예시

public class Freq { public static void main(String[] args) throws FileNotFoundException { File file = new File(args[0]); // 코드 46-1 스트림 패러다임을 이해하지 못한 채 API만 사용했다 - 따라 하지 말 것! (277쪽) Map<String, Long> freq = new HashMap<>(); try (Stream<String> words = new Scanner(file).tokens()) { words.forEach(word -> { freq.merge(word.toLowerCase(), 1L, Long::sum); }); } }
Java
복사

스트림 활용 예시

public class Freq { public static void main(String[] args) throws FileNotFoundException { File file = new File(args[0]); // 코드 46-2 스트림을 제대로 활용해 빈도표를 초기화한다. (278쪽) Map<String, Long> freq; try (Stream<String> words = new Scanner(file).tokens()) { freq = words .collect(groupingBy(String::toLowerCase, counting())); } }
Java
복사

빈도표에서 가장 흔한 단어 10개 뽑아내는 파이프라인

public class Freq { public static void main(String[] args) throws FileNotFoundException { File file = new File(args[0]); // 코드 46-3 빈도표에서 가장 흔한 단어 10개를 뽑아내는 파이프라인 (279쪽) List<String> topTen = freq.keySet().stream() .sorted(comparing(freq::get).reversed()) .limit(10) .collect(toList()); } }
Java
복사

toMap예시

private static final Map<String, Operation> stringToEnum = Stream.of(Operation.values()).collect( toMap(Object::toString, e -> e) ); Map<Aritst, Album> topHits = albums.collect( toMap(Album::artist, a -> a, maxBy(comparing(Album::sales))));
Java
복사
비교자 생성 메서드인 comparing이 maxBy에 넘겨줄 비교자를 반환하는데, 자신의 키 추출 함수로는 Album::sales를 받습니다.
즉 앨범 스트림을 맵으로 바꾸는데, 이 맵은 각 음악가와 그 음악가의 베스트 앨범을 짝지은 것이라는 이야기입니다.

groupingBy 예시

words.collect(groupingBy(word -> alphabetize(word)));
Java
복사
groupingBy가 반환하는 수집기가 리스트 외의 값을 갖는 맵을 생성하게 하려면, 분류 함수와 함께 다운스트림 수집기도 명시해야 합니다.
다운스트림 수집기의 역할은 해당 카테고리의 모든 원소를 담은 스트림으로부터 값을 생성하는 일입니다.
words.collect(groupingBy(String::toLowerCase, counting()));
Java
복사
즉, 각 카테고리를 해당 카테고리에 속하는 특정한 값(원소의 개수 등등)과 매핑한 맵을 얻을 수 있습니다.

References::

이펙티브 자바 / 조슈아 블로크 지음 (프로그래밍 인사이트)