/////
Search
Duplicate
1️⃣

스트림이란 무엇인가?

스트림은 자바 8 API에 새로 추가된 기능으로 스트림을 이용하면 선언형으로 컬렉션 데이터를 처리할 수 있다.
스트림이 데이터 컬렉션 반복을 처리하는 기능이라고 생각하자. 스트림을 사용하면 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있다.
스트림의 병렬 처리는 이후 자세하게 설명하므로 우선은 스트림이 어떤 유용한 기능을 제공하는지 확인하자.
다음 예제는 저칼로리의 요리명을 반환하고 칼로리를 기준으로 요리를 정렬하는 자바 7 코드다.
List<Dish> lowCaloricDishes = new ArrayList<>(); for(Dish dish: menu) { if(dish.getCalroies() < 400) { lowCaloricDishes.add(dish); } } Collections.sort(lowCaloricDishes, new Comparator<Dish>() { public int compare(Dish dish1, Dish dish2) { return Integer.compare(dish1.getCalroies(), dish2.getCalroies()); } }); List<String> lowCaloricDishesName = new ArrayList<>(); for(Dish dish: lowCaloricDishes) { lowCaloricDishesName.add(dish.getName()); }
Java
복사
다음은 최신 코드다.
List<String> lowCaloricDishesName = menu.stream() .filter(d -> d.getCalories() < 400) .sorted(comparing(Dish::getCalroies)) .map(Dish::getName) .collect(toList());
Java
복사
stream()parallelStream()으로 변경하면 이 코드를 멀티코어 아키텍처에서 병렬로 실행하게 할 수 있다.
parallelStream()을 호출했을 때 정확히 어떤 일이 일어날까? 얼마나 많은 스레드가 사용되는 걸까? 얼마나 성능이 좋을까? 이는 7장에서 설명한다.
일단은 스트림의 새로운 기능들이 소프트웨어공학적으로 다음과 같은 다양한 이득을 준다는 것만 기억하자.
선언형으로 코드를 구현할 수 있다. 즉 루프와 if 조건문 등의 제어 블록을 사용해서 어떻게 동작을 구현할지 지정할 필요없이, 동작의 수행을 지정할 수 있다.
filter, sorted, map, collect같은 여러 빌딩 블록 연산을 연결해서 복잡한 데이터 처리 파이프라인을 만들 수 있다. 여러 연산을 파이프라인으로 연결해도 여전히 가독성과 명확성이 유지된다.
filter같은 연산은 고수준 빌딩 블록으로 이루어져 있으므로 특정 스레딩 모델에 제한되지 않고 자유롭게 어떤 상황에서든 사용할 수 있다.
결과적으로 우리는 데이터 처리 과정을 병렬화하면서 스레드와 락을 걱정할 필요가 없다. 이 모든 것이 스트림 API 덕분이다.
자바 8의 API의 특징을 다음처럼 요약할 수 있다.
선언형 : 더 간결하고 가독성이 좋아진다.
조립할 수 있음 : 유연성이 좋아진다.
병렬화 : 성능이 좋아진다.