/////
Search
Duplicate
4️⃣

스트림

거의 모든 자바 애플리케이션은 컬렉션을 만들고 활용한다. 하지만 컬렉션으로 모든 문제를 해결할 수 있는 것은 아니다.
예를 들어 리스트에서 고가의 거래내역만 필터링하고 통화로 결과를 그룹화한다고 가정하자.
다음과 같이 수많은 코드를 구현해야 한다.
Map<Curreny, List<Transaction>> transactionByCurrencies = new HashMap<>(); for(Transaction transaction : transactions) { if(transaction.getPrice() > 1000) { Curreny curreny = transacation.getCurrency(); List<Transcation> transactionsForCurrency = transactionsByCurrencies .get(currency); if(transactionsForCurrency == null) { transactionsForCurrency = new ArrayList<>(); transactionsByCurrencies.put(currenc, transcationsForCurrency); } transactionsForCurrency.add(transacation); } }
Java
복사
Stream API를 이용하면 다음처럼 문제를 해결할 수 있다.
import static java.util.stream.Collectors.groupingBy; Map<Currency, List<Transaction>> transactionsByCurrencies = transactions.stream() .filter((Transcations t) -> t.getPrice() > 1000); // 고가의 트랜잭션 필터링 .collect(groupingBy(Transcation::geturrency)); // 통화로 그룹화
Java
복사
Stream API를 이용하면 Collection API와는 상당히 다른 방식으로 데이터를 처리할 수 있다는 사실만 기억하자.
for-each 루프를 이용한 반복을 외부 반복이라고 한다. Stream API에서는 라이브러리 내부에서 모든 데이터가 처리된다. 이를 내부 반복이라고 한다.

1. 멀티스레딩은 어렵다.

멀티스레딩 환경에서 각각의 스레드는 동시에 공유된 데이터에 접근하고 데이터를 갱신할 수 있다. 결과적으로 스레드를 잘 제어하지 못하면 동시성을 깨치게 된다.
자바 8은 Stream API컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드 문제 그리고 멀티코어 활용 어려움이라는 두 가지 문제를 모두 해결했다.
기존의 컬렉션에서는 데이터를 처리할 때 반복되는 패턴이 너무 많았어서 이러한 반복되는 패턴을 라이브러리가 제공하면 좋을 것이라는 요구에 따라 만들어지게 된 것이다.
주어진 조건에 따라 데이터를 필터링하거나, 추출, 그룹화하는 등의 기능이 있다. 또한 이런 동작들을 쉽게 병렬화할 수 있다는 점도 변화의 동기가 되었다. ⇒ 빅데이터를 아주 잘 처리하려고 만들었다
예를 들어 하나의 CPU가 리스트의 앞부분을 처리하고 다른 CPU가 리스트의 뒷부분을 처리하도록 요청할 수 있다. 각각의 CPU는 자신이 맡은 절반의 리스트를 처리한 후, 하나의 CPU가 두 결과를 정리한다.
지금은 새로운 Stream API도 기존의 Collection API와 아주 비슷한 방식으로 처리할 것이라고 간주할 것이다.
다만 컬렉션은 어떻게 데이터를 저장하고 접근할지에 중점을 두고 스트림은 데이터에 어떤 계산을 할 것인지 묘사하는 것에 중점을 둔다는 것을 기억하자.
스트림은 스트림 내의 요소를 쉽게 병렬로 처리할 수 있는 환경을 제공한다는 것이 핵심이다.
자바 8에서 제공하는 두 가지 요술방망이
흔히 사람들은 자바의 병렬성은 어렵고 synchronized는 쉽게 에러를 일으킨다고 생각한다.
자바 8은 어떻게 병렬성을 쉽고 간편하게 제공할까?
자바 8은 두 가지 요술 방망이를 제공한다.
우선 라이브러리에서 분할을 처리한다.
큰 스트림을 병렬로 처리할 수 있도록 작은 스트림으로 분할한다. 또한 filter 같은 라이브러리 메서드로 전달된 메서드가 상호작용을 하지 않는다면 가변 공유 객체를 통해 공짜로 병렬성을 누릴 수 있다.
상호작용을 하지 않는다는 제약은 프로그래머 입장에서 상당히 자연스러운 일이다.
함수형 프로그래밍에서 함수란 함수를 일급값으로 사용한다라는 의미도 있지만, 부가적으로 프로그램이 실행되는 동안 컴포넌트 간에 상호작용이 일어나지 않는다라는 의미도 포함한다.