Dev 달팽이 @_''

[모던 자바 인 액션] 4장 스트림 소개 본문

Java&Spring/모던 자바 인 액션

[모던 자바 인 액션] 4장 스트림 소개

다본죽 2022. 6. 28. 18:05

4.1 스트림이란 무엇인가?

스트림은 자바 8 API에 새로 추가된 기능이다. 스트림을 이용하면 선언형(데이터를 처리하는 임시 구현 코드 대신 질의로 표현할 수 있다.)으로 컬렉션 데이터를 처리 할 수 있다. 또한, 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있다. 

 

예제. 저칼로리의 요리명을 반환하고, 칼로리를 기준으로 요리를 정렬하는 자바 코드

 

자바 7 코드

List<Dish> lowCaloricDishes = new ArrayList<>();
for(Dish dish : mene) {
	if(dish.getCalories() < 400) {
    	lowCaloricDishes.add(dish);
    }
}

Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
	public int compare(Dish dish1, Dish dish2) {
    	return Integer.compare(dish1.getCalories(), dish2.getCalories());
    }
});

List<String> lowCaloricDishesName = new ArrayList<>();
for(Dish dish : lowCaloricDishes) {
	lowCaloricDishesName.add(dish.getName());
}

위 코드에서 lowCaloricDishes라는 '가비지 변수'를 사용했다. 즉, lowCaloricDishes는 컨테이너 역할만 하는 중간 변수다.

자바 8에서는 이러한 세부 구현은 라이브러리 내에서 모두 처리한다.

 

자바 8 코드

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;

List<String> lowCaloricDishesName =
	menu.stream()
    	.filter(d->d.getCalories() < 400)
        .sorted(comparing(Dish::getCalories))
        .map(Dish::getName)
        .collect(toList());

stream()을 parallelStream()으로 바꾸면 이 코드를 멀티코어 아키텍처에서 병렬로 실행할 수 있다.

List<String> lowCaloricDishesName =
	menu.parallelStream()
    	.filter(d->d.getCalories() < 400)
        .sorted(comparing(Dish::getCalories))
        .map(Dish::getName)
        .collect(toList());

 

스트림의 새로운 기능이 주는 소프트웨어공학적 이득

  • 선언형으로 모든 코드를 구현할 수  있다.
  • filter, sorted, map, collect 같은 여러 빌딩 블록 연산을 연결해서 복잡한 데이터 처리 파이프라인을 만들 수 있다.

filter(또는 sorted, map, collect) 같은 연산은 고수준 빌딩 블록으로 이루어져 있으므로 특정 스레딩 모델에 제한되지 않고 자유롭게 어떤 상황에서든 사용할 수 있다. 결과적으로 우리는 데이터 처리 과정을 병렬화하면서 스레드와 락을 걱정할 필요가 없다.

자바 8의 스트림 API의 특징을 다음처럼 요약할 수 있다.

  • 선언형 더 간결하고 가독성이 좋아진다.
  • 조립할 수 있음 : 유연성이 좋아진다.
  • 병렬화 : 성능이 좋아진다.

4.2 스트림 시작하기