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

June·2022년 2월 27일
0

[이펙티브자바]

목록 보기
41/72

스트림은 그저 API가 아니라 함수형 프로그래밍에 기초한 패러다임이다. 그래서 이 패러다임까지 함께 받아들여야 한다.

스트림 패러다임의 핵심은 계산을 일련의 변환으로 재구성하는 부분이다. 이때 각 변환 단계는 가능한 이전 단계의 결과를 받아 처리하는 순수 함수여야 한다. 순수 함수란 오직 입력만이 결과에 영향을 주는 함수를 말한다. 다른 가변 상태를 참조하지 않고, 함수 스스로도 다른 상태를 변경하지 않는다. 이렇게 하려면 스트림 연산에 건네는 함수 객체는 모두 사이드 이펙트가 없어야 한다.

스트림을 이해 못하고 api만 사용

Map<String, Long> freq = new HashMap<>();
try (Stream<String> words = new Scanner(file).tokens()) {
    words.forEach(word -> {
        freq.merge(word.toLowerCase(), 1L, Long::sum);
    });
}

텍스트 파일에서 단어별 수를 세어 빈도표를 만든다. 문제는 forEach에서 일어나느데, 이때 빈도표를 수정하는 람다를 실행하면서 문제가 생긴다. forEach가 그저 스트림의 연산 결과 보여주기 이상을 하면 나쁜 코드일 가능성이 크다.

**스트림 잘 활용&&

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(groupingBy(String::toLowerCase, counting()));
}

forEach 연산은 스트림 계산 결과를 보고할 때만 사용하고, 계산하는데는 쓰지말자

Collector를 사용하면 스트림의 원소를 손쉽게 컬렉션으로 모을 수 있다. collector는 총 세가지로, toList(), toSet(), toCollection(collectionFactory)가 가능한데, 리스트, 집합, 프로그래머 지정 컬렉션 타입을 반환한다.

279 이어보기

0개의 댓글