본문 바로가기

Effective Java

[이펙티브 자바] 아이템 45. 스트림은 주의해서 사용하라

 

1) 스트림이란?

- 스트림 API는 다량의 데이터 처리 작업(순차적이든 병렬적이든)을 돕고자 자바8에 추가되었다.

  이 API가 제공하는 추상 개념 중 핵심은 두 가지다.

  그 첫 번째인 스트림(stream)은 데이터 원소의 유한 혹은 무한 시퀀스(sequence)를 뜻한다.

  두 번째인 스트림 파이프라인(stream pipeline)은 이 원소들로 수행하는 연산 단계를 표현하는 개념이다.

  스트림의 원소들은 어디로부터든 올 수 있다.

  대표적으로는 컬렉션, 배열, 파일, 정규표현식 패턴 매처(matcher), 난수 생성기, 혹은 다른 스트림이 있다.

  스트림 안의 데이터 원소들은 객체 참조나 기본 타입 값이다.

  기본 타입 값으로는 int, long, double 이렇게 세 가지를 지원한다. 

 

 

2) 스트림 파이프라인

- 스트림 파이프라인은 소스 스트림에서 시작해 종단 연산(terminal operation)으로 끝나며,

   그 사이에 하나 이상의 중간 연산(intermediate operation)이 있을 수 있다.

   각 중간 연산은 스트림을 어떠한 방식으로 변환(transform)한다.

   예컨대, 각 원소에 함수를 적용하거나 특정 조건을 만족 못하는 원소를 걸러낼 수 있다.

   중간 연산들은 모두 한 스트림을 다른 스트림으로 변환하는데, 

   변환된 스트림의 원소 타입은 변환 전 스트림의 원소 타입과 같을 수도 있고 다를 수도 있다.

   종단 연산은 마지막 중간 연산이 내놓은 스트림에 최후의 연산을 가한다.

   원소를 정렬해 컬렉션에 담거나, 특정 원소 하나를 선택하거나, 모든 원소를 출력하는 식이다.

 

 

3) 스트림의 지연 평가(lazy evaluation)

- 스트림 파이프라인은 지연 평가(lazy evaluation)된다. 평가는 종단 연산이 호출될 때 이뤄지며,

  종단 연산에 쓰이지 않는 데이터 원소는 계산에 쓰이지 않는다.

  이러한 지연 평가가 무한 스트림으 다룰 수 있게 해주는 열쇠다.

  종단 연산이 없는 스트림 파이프라인은 아무 일도 하지 않는 명령어인 no-op과 같으니,

  종단 연산을 빼먹는 일이 절대 없도록 하자. 

 

 

4) 스트림의 메서드 연쇄(method chaining)

- 스트림 API는 메서드 연쇄를 지원하는 플루언트 API다.

  즉, 파이프라인 하나를 구성하는 모든 호출을 연결하여 단 하나의 표현식으로 완성할 수 있다.

  파이프라인 여러 개를 연결해 표현식 하나로 만들 수도 있다. 

 

 

5) 스트림의 순차적 수행

- 기본적으로 스트림 파이프라인은 순차적으로 수행된다.

  파이프라인을 병렬로 실행하려면 파이프라인을 구성하는 스트림 중 하나에서 parallel 메서드를 

  호출해주기만 하면 되나, 효과를 볼 수 있는 상황은 많지 않다.