Java8 Stream examples

roon2020·2021년 4월 2일
0

Java

목록 보기
2/2
post-thumbnail

Stream은 Collection을 개선,보완해서 자바8부터 새로 만들어진 것입니다.
기본적으로 연속적으로 데이터를 처리한다는 점에서 Collection과 같습니다. 차이점으론 Collection은 "어떻게" 데이터를 처리할 지에 관심을 가지는 반면, Stream은 SQL 쿼리처럼 "그래서,원하는 게 뭔데?"라는 것에 관심을 뒀습니다. 데이터를 처리하는 구체적인 구현은 내부적으로 최적화되어 실행됩니다. (Collection을 다루기에 최적화 되어있다는 뜻입니다. 즉, 순차적으로 접근합니다.)

자바7 이하에서는 꽤 복잡하게 구현해야 할 것들을 간단히 구현할 수 있습니다.
또 stream을 parallalStream으로 얻는 것만으로 병렬처리가 가능해집니다.

자료는 모던 자바 인 액션을 참고했습니다.

간단한 예제

주어진 수열에서 3보다 큰 짝수들을 제곱하고 정렬하여 출력하기

 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);

간단히 설명하면

  1. Arrays.stream(배열)으로 스트림을 얻습니다.
  2. filter의 Predicate를 람다식으로 구현하여 넘겨줍니다. 이에 따라 필터링 합니다.
  3. map을 사용하여 제곱값으로 mapping(변환)을 합니다.
  4. sorted를 사용하여 정렬한 스트림을 반환합니다.
  5. forEach에 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()를 이용해서 시간을 측정해봤습니다.
시간 차이를 비교해보면 병렬로 하는게 많이 더 빠르네요.

이 글에서 다루지 않은 내용

  • 병렬 수행 원리
  • 병렬 수행을 할 수 있는 조건
  • Collectors.collect()를 활용한 리듀싱,그룹화,분할
  • 스트림 요소 검색(findAny 등)
  • 박싱,언박싱, 특화된 스트림

스트림의 여러가지 내용 중 일부를 간단한 예제를 통해 알아본 것이니 자세한 사항은 책을 참고하셔야 합니다!

profile
keep in positive mindset. I've got this.

0개의 댓글