데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소(Sequence of elements)
스트림은 Java8때부터 지원이 시작되었다.
병렬처리 가능한 이점이 있지만. 한번만 탐색 가능하다는 단점 또한 존재한다.
스트림은 불필요한 코드 길이 및 for, if같은 조건문과 반복문을 줄이기 위해 사용된다.
이때까지 사용해오던 컬렉션과 다른 점이 존재하고 각자 사용하므로써 얻을 수 있는 점이 있는데 이는 아래에서 기술하도록 하겠다.
선언형 | 조립할 수 있음 | 병렬화 |
---|---|---|
간결하고 가독성 좋아짐 | 유연성 좋아짐 | 성능 좋아짐 |
• 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프 라인을 구성할 수 있도록 스트림 자신을 반환한다.
연산 파이프라인은 데이터 소스에 적용하는 데이터베이스 질의와 비슷하다.
반복자를 명시적으로 표현하지 않고 내부적으로 반복한다.
스트림은 딱 한번만 반복가능하다.
게으르다(lazy)
lazy란?
실제로 필요해지는 경우에 연산을 시작한다.
쇼트서킷(shortcircuiting)
shortcircuiting이란?
💡 **조건1 && 조건2 일 경우**연산자의 앞 조건식의 결과에 따라 뒤 조건식의 실행 여부를 결정한다.
조건1이 false라면 조건2를 실행하지 않고 생략한다.
(조건1이 false라면 조건1 && 조건2는 항상 false이기 때문)
💡 **조건1 || 조건2 일 경우**조건1이 true라면 조건2를 실행하지 않고 생략한다.
(조건1이 true라면 조건1 || 조건2는 항상 true이기 때문)
1) 예제코드
// 외부 반복
List<String> names = new ArrayList<>();
for(Coffee c:menu) {
names.add(c.getName());
}
// 내부 반복
List<String> names = menu.stream()
.map(Coffee::getName)
.collect(toList());
forEach를 이용하는 외부 반복
은 병렬성을 스스로 관리해야 함.
스트림의 내부 반복
은 데이터 표현과 병렬성을 자동으로 관리한다.
(필터링, 슬라이싱, 검색, 매칭, 매핑, 리듀싱 등)
데이터를 요청할때만 요소를 계산한다.
게으른 생성, 요청 중심 제조, 즉석 제조
ex) 유튜브 스트리밍
모든 값을 메모리에 저장함. 즉 컬렉션의 모든 요소는 추가되기 전 계산되어야 한다.
적극적 생성, 생산자 중심(팔기 전에 창고 채움)
ex) DVD
중간연산
ex) filter
map
limit
sorted
distinct
filter
: 프레디케이트(boolean 반환 함수)를 인수로 받아 일치하는 모든 요소를 포함하는 스트림 반환
최종연산
distinct
: 고유요소로 이루어진(하나만) 스트림 반환
ex) forEach
count
collect
스트림 활용
5.1 필터링
filter
distinct
사용
filter
:
distinct
: 고유 요소 필터링
5.2 슬라이싱
takeWhile
dropWhile
limit
skip
사용
takeWhile
: 이미 정렬되어 있는 스트림에서 사용됨. 기준값보다 크거나 작은 요소만 빠르게 가져올 수 있다.
프레디케이트가 처음으로 거짓되는 지점까지 요소 가져옴
(약간 while문 돌다가 만족하면 break해서 나오는 것 같은 느낌)
dropWhile
: takeWhile
과 반대작업 수행.
프레디케이트가 처음으로 거짓되는 지점까지 요소 버림.
limit
: 정렬되어 있으면 최대 요소 n개를 반환할 수 있다.
skip
: 처음 n개 요소를 제외한 스트림을 반환할 수 있다.
5.3 매핑
5.4 검색
5.5 매칭
5.6 리듀싱
숫자스트림
파일과 배열로 스트림 만들기
무한 스트림