# chapter 4. 스트림 소개
-. 스트림이란
데이터 컬렉션 반복을 멋지게 처리하는 기능.
cf> 스트림을 이용하면 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있다.
[JAVA 7]
List<Dish> lowColoricDishes = new ArrayList<>();
for(Dish dish : menu) {
if(dish.getCalory() < 400) {
lowColoricDishes.add(dish);
}
}
Collections.sort(lowColoricDishes, new Comparator<Dish>() {
public int compare(Dish dish1, Dish dish2) {
return Integer.compare(dish1.getCalory(), dish2.getCalory());
}
});
List<String> lowCaloricDishesName = new ArrayList<>();
for(Dish dish : lowColoricDishes) {
lowCaloricDishesName.add(dish.getName());
}
[JAVA 8]
import static java.util.Comparator.comparing;
import static java.uti;l.stream.Collectors.toList;
List<String> lowCaloricDishesName = menu.stream()
.filter(d -> d.getCalory() < 400) // 400칼로리 이하의 요리 선택
.sorted(comparing(Dish::getCalory)) // 칼로리로 요리 정렬
.map(Dish::getName) // 요리명 추출
.collect(toList()); // 모든 요리명을 리스트에 저장
filter 같은 연산은 고수준 빌딩 블록으로 이루어져 있으므로 특정 스레딩 모델에 제한되지 않고 자유롭게 어떤 상황에서든 사용할 수 있다.
결과적으로 우리는 데이터 처리 과정을 병렬화하면서 스레드와 락을 걱정할 필요가 없다. 이 모든 것이 스트림 API 덕분이다.
자바 8의 스트림 API 특징
|
-. 스트림 이란
데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소
-
연속된 요소
컬렉션과 마찬가지로 스트림은 특정 요소 형식으로 이루어진 연속된 값 집합의 인터페이스를 제공한다.
but, 컬렉션의 주제는 데이터이고 스트림의 주제는 계산이다.
-
소스
스트림은 컬렉션, 배열, I/O 자원등의 데이터 제공 소스로부터 데이터를 소비한다.
즉, 정렬된 컬렉션으로 스트림을 생성하면 정렬이 그대로 유지된다.
-
데이터 처리 연산
스트림은 함수형 프로그래밍 언어에서 일반적으로 지원하는 연산과 데이터베이스와 비슷한 연산을 지원한다.
ex> filter, map, reduce, find, match
스트림 연산은 순차적으로 또는 병렬로 실행할 수 있다.
스트림의 중요한 2가지 특징
대부분의 스트림연산은 스트림 연산끼리 연결해서 커다란 파이프 라인을 구성할 수 있도록 스트림 자신을 반환한다. 연산 파이프라인은 데이터 소스에서 적용하는 데이터베이트 질의와 비슷하다.
반복자를 이용해서 명시적으로 반복하는 컬렉션과 달리 스트림은 내부 반복을 지원한다. |
스트림도 딱 한번만 탐색할 수 있다.
한번 탐색한 요소를 탐색하고 싶다면?) 초기 데이터 소스에서 새로운 스트림을 만들어야 한다.
컬렉션과 스트림의 또 다른 차이는 데이터 반복 처리 방법이다.
-
내부반복 : 스트림
-
외부반복 : 컬렉션
-. 중간연산
스트림을 반환하며 서로 연결할 수 있는 연산
[sample] filter, map, limit 중간연산에 해당
List<String> names = menu.stream()
.filter(dish -> dish.getCalories() > 300)
.map(Dish::getName)
.limit(3)
.collect(toList());
[debug]
List<String> names = menu.stream()
.filter(dish -> {
System.out.println("filtering:" + dish.getName());
dish.getCalories() > 300
})
.map(dish ->
System.out.println("mapping:" + dish.getName());
return dish.getName();
})
.limit(3)
.collect(toList());
System.out.println(names);
[output]
filtering:pork
mapping:pork
filtering:beef
mapping:beef
filtering:chicken
mapping:chicken
[pork, beef, chicken]
=> 하나의 데이터가 중간 연산(filter -> map)과정을 다 돌고나서 다음 데이터를 처리한다.
[참고] 중간연산
연산 |
형식 |
반환형식 |
연산의 인수 |
함수 디스크립터 |
filter |
중간연산 |
Stream<T> |
Predicate<T> |
T -> boolean |
map |
중간연산 |
Stream<R> |
Function<T, R> |
T -> R |
limit |
중간연산 |
Stream<T> |
|
|
sorted |
중간연산 |
Stream<T> |
Comparator<T> |
(T, T) -> int |
distinct |
중간연산 |
Stream<T> |
|
|
[참고] 최종연산
연산 |
형식 |
반환 형식 |
목적 |
forEach |
최종연산 |
void |
스트림의 각 요소를 소비하면서 람다를 적용한다. |
count |
최종연산 |
long |
스트림의 요소 개수를 반환한다 |
collect |
최종연산 |
|
스트림을 리듀스해서 리스트, 맵, 정수 형식의 컬렉션을 만든다. |
'언어 > java' 카테고리의 다른 글
[모던자바 인액션]#2 동작 파라미터화 코드 전달 (0) | 2021.01.13 |
---|---|
[모던자바 인액션]#3 람다 표현식 (0) | 2021.01.13 |
[JAVA] String으로 입력된 날짜의 차이 구하기 (0) | 2019.10.25 |
[날짜 차이] 현재 날짜와 특정 날짜 지났는지 check (0) | 2019.05.28 |
자료구조 정리 (0) | 2018.12.08 |