스트림의 기본개념

반응형
728x90
반응형

도입

모든 자바 애플리케이션은 컬렉션을 만들고 처리하는 과정을 포함한다. 컬렉션은 대부분의 프로그래밍 작업에 사용될 정도로 어디서든 사용되어지고있다. 하지만 컬렉션을 많이 사용함에도 불구하고 완벽한 컬렉션 연산을 지원하기에는 아직까지도 부족하다. 많은 요소를 포함하는 컬렉션은 어떻게 처리해야할까?

 

성능을 높이려면 멀티코어 아키텍처를 활용하여 병렬로 컬렉션의 요소를 처리해야한다. 하지만 병렬 처리 코드를 구현하는 것은 단순 반복 처리 코드에 비해 복잡하고 어렵다. 이러한 복잡한 코드는 디버깅도 어렵다. 프로그래머가 귀중한 시간을 절약하고, 편리한 삶을 누릴 수 있도로 자바 언어 설계자들이 내린 결정이 바로 스트림이다.

 

 

스트림이란?

스트림은 자바 8 API에 새로 추가된 기능이다. 스트림은 데이터 컬렉션 반복을 처리하는 기능으로, 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있다.

 

아래 예제를 보며 스트림의 코드를 확인해보자.

List<Dish> lowCaloricDishes = new ArrayList<>();
for (Dish dish : menu) { // (1) 400 칼로리 이하의 요리 선택
  if(dish.getCalories() < 400) {
    lowCaloricDishes.add(dish);
  }
}

Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
  pubic int compare(Dish dish1, Dish dish2) { // (2) 정렬
    return Integer.compare(dish1.getCalories(), dish2.getCalories());
  }
});

List<String> lowCaloricDishesName = new ArrayList<>();
for(Dish dish : lowCaloricDishes) { // (3) getName 메소드를 참조하여 요리명 추출, (4) 리스트에 저장
  lowCaloricDishesName.add(dish.getName());
}

 

자바 8에서는 위 코드를 스트림을 사용하여 간결하고 가독성있게 변환시킬 수 있다.

List<String> lowCaloricDishesName = 
            menu.stream()
              .filter(d -> d.getCalories() < 400) // (1) 400 칼로리 이하의 요리 선택
              .sorted(comparing(Dish::getCalories)) // (2) 정렬
              .map(Dish::getName) // (3) getName 메소드를 참조하여 요리명 추출
              .collect(toList()); // (4) 리스트에 저장

 

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

ist<String> lowCaloricDishesName = 
            menu.parallelStream()
              .filter(d -> d.getCalories() < 400) // (1) 400 칼로리 이하의 요리 선택
              .sorted(comparing(Dish::getCalories)) // (2) 정렬
              .map(Dish::getName) // (3) getName 메소드를 참조하여 요리명 추출
              .collect(toList()); // (4) 리스트에 저장

 

filter, sorted, map, collect 같은 여러 빌딩 블록 연산을 연결해서 복잡한 데이터 처리 파이프 라인을 만들 수 있다. 여러 연산을 파이프라인으로 연결해도 여전히 가독성과 명확성이 유지된다.

 

filter(람다) -> sorted(람다) -> map(람다) -> collect

 

filter 메서드의 결과는 sorted 메서드로, 다시 sorted 결과는 map 메서드로, map 메서드의 결과는 collect 연결된다.

 

 

 

스트림의 장점

선언형으로 코드를 구현할 수 있다. 루프와 if 조건문 등의 제어 블록을 사용할 필요가 없다. 코드가 더 간결하고 가독성이 좋아진다. 또한 코드의 유연성이 좋아지며, 병렬화를 통한 성능이 향상이 가능하다.

 

반응형

'Coding > Java' 카테고리의 다른 글

스트림 vs 컬렉션  (0) 2020.11.06
스트림 구현  (0) 2020.11.06
람다의 메서드 참조  (0) 2020.11.06
람다의 형식 검사, 형식 추론, 제약  (0) 2020.11.06
함수형 인터페이스 사용  (0) 2020.11.06

Designed by JB FACTORY