거의 모든 자바 어플리케이션은 컬렉션을 이용하고 처리하기 위해서는 for문과 Iterator를 이용해서 코드를 작성해왔다.
가독성
이 좋지 않으며 재사용성
마저 떨어진다.데이터 소스마다 다른 방식
으로 다뤄야한다. Collection이나 Iterator와 같은 인터페이스를 이용해서 표준화했지만, 각 컬렉션 클래스에는 같은 기능의 메서드들이 중복 정의 되어 있다.많은 요소를 포함하는 컬렉션은 어떻게 처리해야 할까?
병렬
로 컬렉션의 요소를 처리해야 한다.컬렉션으로도 sql 질의처럼 고수준으로 추상화해서 처리할 수 있는 기능과 병렬 처리 기능을 만들 수 없을까??
List<Stirng> names = player.stream()
.filter(player -> player.getAge > 30) // 30살 이상 player 선택
.map(Player::getName) // 요리명 추출
.limit(3) // 선착순 3개만 추출
.collect(toList()); // 스트림을 리스트로 변환
스트림(Stream)은 자바 8 API에 새로 추가된 기능이다.
선언형
으로 컬렉션 데이터를 처리할 수 있다.유연성
이 좋다.병렬
로 처리할 수 있다.스트림이란 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소 로 정의할 수 있다
연속된 요소
: 컬렉션과 마찬가지로 스트림은 특정 요소 형식으로 이루어진 연속된 값 집합의 인터페이스를 제공한다.
소스
: 스트림은 컬렉션, 배열, I/O 자원 등의 데이터 제공 소스로부터 데이터를 소비한다.
데이터 처리 연산
: 스트림은 함수형 프로그래밍 언어에서 일반적으로 지원하는 연산과 데이터베이스와 비슷한 연산을 지원하며, 순차적으로 또는 병렬로 실행할 수 있다.
스트림은 다음과 같은 주요 특성이 있다.
파이프라이닝
게으름(lazyness)
, 쇼트서킷(short-circuiting)
같은 최적화도 얻을 수 있다.내부 반복
자바의 기존 컬렉션과 자바8에서 추가된 스트림 모두 연속된(순차적, sequenced) 요소 형식의 값을 저장하는 자료구조의 인터페이스를 제공한다.
가장 큰 차이는 데이터를 계산하는 시점
이다
모든 값
을 메모리에 저장하는 자료구조이다.요청할 때만 요소를 계산
하는 고정된 자료구조이다.생산자-소비자
관계를 형성하며 게으르게 만들이지는 컬렉션
과 같다.외부 반복(external iteration)
이라고 한다.내부 반복(internal iteration)
을 사용한다. List<String> names = menu.stream()
.map(Dish::getName) // 요리명 추출
.collect(toList()); // 파이프라인 실행, 반복자 x
병렬성
을 쉽게 얻을 수 있다는 점이며, 내부적으로 더 최적화
된 다양한 순서로 처리할 수 있는 점이다.스트림 인터페이스의 연산을 크게 두 가지로 구분할 수 있다.
중간 연산(intermediate operation)
: 연결할 수 있는 스트림 연산최종 연산(terminal operation)
: 스트림을 닫는 연산 List<Stirng> names = menu.stream() // 요리 리스트에서 스트림 얻기
.filter(dish -> dish.getCalories > 300) // 중간 연산 시작
.map(Dish::getname)
.limit(3) // 중간 연산 끝
.collect(toList()); // 스트림을 리스트로 변환, 종단 연산
다른 스트림을 반환
한다.게으르다(lazy)
는 것이다. List<Stirng> names = menu.stream() // 스트림 open
.filter(dish -> {
Syste.out.println("filtering:" + dish.getName());
return dish.getCalories > 300;
})
.map(dish -> {
Syste.out.println("mapping:" + dish.getName());
return dish.getName();
})
.limit(3)
.collect(toList());
filtering:pork
mapping:pork
filtering:beef
mapping:beef
filtering:chicken
mapping:chicken
[pork, beef, chicken]
쇼트 서킷
이다.루프 퓨전
이다.요소를 소모
하므로 단 한번만 가능하다.스트림의 이용과정은 세 가지로 요약 가능하다
스트림의 파이프라인의 개념은 빌더 패턴과 비슷하다.