스터디/이펙티브 자바

[Effective Java] Item45. 스트림은 주의해서 사용하라

📝 작성 : 2022.07.10  ⏱ 수정 : 
728x90

스트림(Stream) API?

스트림 API는 다량의 데이터 처리 작업을 위해 JDK8부터 추가되었습니다.
스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 의미하며, 스트림 파이프라인은 이 원소들로 수행하는 연산단계를 표현하는 개념입니다.
스트림 안의 데이터 원소들은 기본적으로 객체 참조타입이며, int, long, double의 세가지 기본타입을 지원하기도 합니다.

스트림 파이프라인

public static void main(String[] args) {
    List.of("apple", "banana", "car") // 리스트
            .stream() // 소스 스트림
            .filter(s -> s.startsWith("b")) // 중간 연산
            .forEach(System.out::println); // 종단 연산
}

소스 스트림에서 시작해 n개 이상의 중간 연산을 거쳐 종단 연산으로 끝납니다.
각 중간 연산은 스트림을 다른 스트림으로 변환하는데, 변환된 스트림의 원소 타입은 변환 전 스트림의 원소 타입과 같을 수도, 다를 수도 있습니다.

스트림 지연평가(Lazy evaluation)

스트림은 종단 연산에 쓰이지 않는 데이터는 계산을 하지 않습니다. 따라서 종단 연산이 없는 스트림은 아무 일도 하지 않습니다.

코드블럭 vs 람다

코드 블럭에서는 지역변수를 읽고, 수정할 수 있지만 람다 블럭은 final로 명시되어 있거나 이후에 값이 바뀌지 않아 사실상 final인 변수만 읽을 수 있습니다.
코드 블럭에서는 return, break, continue를 이용해 메서드의 종료 또는 반복문의 종료를 할 수 있지만 람다는 불가능 합니다.
또한 람다에서는 메서드 선언에 명시된 예외를 던질 수 도 없습니다.

스트림을 언제 쓸까?

  • 원소들의 시퀀스를 일관되게 변환한다.
  • 원소들의 시퀀스를 필터링한다.
  • 원소들의 시퀀스를 하나의 연산을 사용해 결합한다. (더하기, 연결하기, 최소값 등..)
  • 원소들의 시퀀스를 컬렉션에 모은다
  • 원소들의 시퀀스에서 특정 조건을 만족하는 원소를 찾는다.

스트림을 언제 쓰지 말아야 할까?

  • 데이터가 파이프라인의 여러 단계(stage)를 통과할 때 이 데이터의 각 단계에서의 값들에 동시에 접근하기 어려운 경우
반응형