Stream은 Collection을 개선,보완해서 자바8부터 새로 만들어진 것입니다.
기본적으로 연속적으로 데이터를 처리한다는 점에서 Collection과 같습니다. 차이점으론 Collection은 "어떻게" 데이터를 처리할 지에 관심을 가지는 반면, Stream은 SQL 쿼리처럼 "그래서,원하는 게 뭔데?"라는 것에 관심을 뒀습니다. 데이터를 처리하는 구체적인 구현은 내부적으로 최적화되어 실행됩니다. (Collection을 다루기에 최적화 되어있다는 뜻입니다. 즉, 순차적으로 접근합니다.)
자바7 이하에서는 꽤 복잡하게 구현해야 할 것들을 간단히 구현할 수 있습니다.
또 stream을 parallalStream으로 얻는 것만으로 병렬처리가 가능해집니다.
자료는 모던 자바 인 액션을 참고했습니다.
int[] numbers ={7,1,2,6,5,3,4,8};
Arrays.stream(numbers)
.filter(x->x>3 && x%2==0)
.map(x->x*x)
.sorted()
.forEach(System.out::println);
간단히 설명하면
배열(int[] 타입)이 아니라 Collection 타입에서는 바로 stream을 얻을 수 있습니다. 마지막에 collect를 사용해서 원하는 타입으로 변환도 가능합니다.
List<Integer> numbers2 = Arrays.asList(1,2,3,4);
List<Integer> result = numbers2.stream()
.filter(x->x>3 && x%2==0)
.map(x->x*x)
.sorted()
.collect(Collectors.toList());
앞에서 Stream을 배열,컬렉션 타입같은 크기가 고정된,주어진 소스로부터 얻었습니다. 하지만 스트림을 직접 만들 수도 있습니다. 이 때 iterate,generate를 사용합니다. 이 스트림은 무한히 계속 만들어 질 수 있기 때문에 limit()으로 truncate해줘야 합니다.
Stream.iterate(new int[]{0,1},t->new int[] {t[1],t[0]+t[1]})
.limit(10)
.forEach(t-> System.out.println(t[0]));
List<Integer> numbers= Arrays.asList(1,2,3);
List<Integer> numbers2 = Arrays.asList(4,5,6);
numbers.stream()
.flatMap(i->numbers2.stream()
.map(j-> new int[]{i,j})
)
.collect(toList());
flatMap은 하나의 스트림으로 만들어주는 map입니다.
만약 위 코드에서 flatMap대신 map을 쓰면 collect 직전에 Stream<Integer[]>일 것입니다. flatMap을 쓰면 Stream< Integer >가 됩니다.
int sum=numbers.stream()
.reduce(0,(a,b)->a+b);
reduce(초기값,연산)을 이용해서 구할 수 있습니다.
여기서 병렬로 처리하려면 단순히 parallelStream으로 스트림을 얻으면 됩니다.
int sum2=numbers.parallelStream()
.reduce(0,(a,b)->a+b);
JMH같은 벤치마크를 이용해서 스탑워치를 해야하지만 간단히 비교해보기 위해 currentTimeMills()를 이용해서 시간을 측정해봤습니다.
시간 차이를 비교해보면 병렬로 하는게 많이 더 빠르네요.
스트림의 여러가지 내용 중 일부를 간단한 예제를 통해 알아본 것이니 자세한 사항은 책을 참고하셔야 합니다!