Stream과 Collection 차이
지난 포스팅부터 "본격 선언형 프로그래밍을 할 수 있게 해준 Stream API" 에 대해 포스팅하고 있습니다.
(모던해지는 자바에서 lambda와 더불어 선언형 프로그래밍이 어느정도 대세가 되지 않을까요? ㅡㅡ^)
오늘 포스팅에서는 "데이터 처리 연산을 지원하도록 추출된 연속된 요소 (JAVA8 IN ACTION 에서 인용)" 인 Stream 과 기존 Collection 의 차이에 대해 포스팅해보려 합니다.
여기에서 연속된 요소라는 정의는 순차적으로 접근가능한 요소라는 점에서, Collection 과 Stream의 큰 차이는 데이터 저장 우선 vs 연산 우선 이라 볼 수 있을 것 같네요.
기존 Collection 은 데이터를 어떻게 잘 저장하고 접근할 것이냐에 초점을 맞췄습니다. 내부 요소에 대한 처리를 하기 위해서는 외부적으로 for-loop 를 통해 각각의 데이터에 접근하며, 비지니스 로직을 처리해야 합니다(외부 반복). 즉 어떤 처리를 위해서 Collection 내부에 모든 값을 가지고 있어야 합니다.
반면 Stream 의 경우 어떻게 처리를 할 것인가에 초점을 맞췄는데요. Stream 은 내부적으로 반복 과정을 숨겨 알아서 처리하고 결과를 어딘가에 출력하는 과정을 수행합니다. (내부 반복) 내부 반복을 사용하는 덕분에 우리는 컨테이너 처리에 대하여 순차적으로나 병렬적으로 처리를 간단하게 설정할 수 있게 되었어요. 아래 코드는 순차처리와 병렬 처리에 대한 간단한 코드입니다.
1 2 3 4 5 6 7 8 9 10 | dataList.stream().filter((a) -> a % 7 == 0).sorted((a, b) -> b.compareTo(a)).limit(4) .forEach(System.out::println); // 순차 처리 dataList.parallelStream().filter((a) -> a % 7 == 0).sorted((a, b) -> a.compareTo(b)).limit(4) .forEach(System.out::println); // 병렬 처리 /* * 위의 코드 중 병렬 처리는 의도된 결과가 나오지 않습니다. 병렬로 처리를 하기 때문에 * parallelStream 의 사용은 "이 일이 병렬로 처리가능한가?" 를 생각해보고 사용해야합니다. */ | cs |
또한 Stream 의 처리 과정은 이론적으로 요청하는 값에 대해서만 처리를 하겠다는 핵심적인 내용이 있습니다. 이 것은 요청할 때만 처리하여, collection은 게으르게 만들겠다는 소리인데... 이 것 역시 예제로 보면 좋을 것 같아요.
무한한 짝수를 표현해야하는 컨테이너의 문제에 대하여,
Collection은 아래과 같이 데이터를 우선적으로 만들고 있어, 소비는 할 수 없네요.
1 2 3 4 5 6 7 8 | ArrayList<Integer> intList = new ArrayList<>(); for (int i = 0;; i+=2) { intList.add(i); } // 영원히 소비가 불가능합니다. for (int i = 0, size = intList.size(); i < size; ++i){ System.out.println(intList.get(i)); } | cs |
반면 Stream 의 경우 무한한 짝수를 모두 만들기보다는 들어오는 요청에 대해서 즉시 만들어 소비하죠. (연속적인 요소가 어떻게 처리가 되는지에 대한 과정을 보기 위한 것이므로, for-loop 내부에 log 를 찍는 경우는 생각안하겠습니다.)
1 2 3 4 | IntStream intList = IntStream.iterate(0, (i) -> i+2);; intList.forEach(System.out::println); // result : 0,2,4,6 ...... | cs |
사실 이러한 특성들은 사실 모두 비지니스 로직으로 풀어갈 수 있는 문제로 보이네요.
하지만 이러한 것들을 미리 알아두는 게, 보다 더 편리하고 뻐그없겠금 사용할 수 있게 도와주지 않을까요?
|
'개발이야기 > 함수형 프로그래밍' 카테고리의 다른 글
Stream API 활용편2 (매핑) (0) | 2016.08.27 |
---|---|
Stream API 활용편1 (필터와 슬라이싱) (0) | 2016.08.26 |
Stream API (0) | 2016.08.03 |
람다 조합 (0) | 2016.08.02 |
메서드 레퍼런스 (0) | 2016.08.01 |