스트림(Stream)
https://yoo-dev.tistory.com/38참고
- 선언형으로 컬렉션 데이터를 처리
- 컬렉션은 자료구조로 요소의 저장 및 접근 연산이 주를 이루는 반면, 스트림은 표현 계산식이 주
(컬렉션의 주제는 데이터이고, 스트림의 주제는 계산)
- 정렬된 컬랙션으로 스트림을 생성시 정렬이 그대로 유지
- 파이프라이닝 : 대부분의 스트림 연산은 스트림 자신을 반환하기 때문에 스트림 연산끼리 연결가능
- 내부 반복 : 컬렉션은 반복자를 이용하여 명시적으로 반복을 하지만, 스트림은 내부에서 반복이 일어나는 연산들을 지원하기 때문에 명시적으로 반복을 할 필요가 없다.
(내부 반복을 이용하면 작업을 투명하게 병렬로 처리하거나 더 최적화된 다양한 순서로 처리할 수 있다.)
-
종류
Stream<> : 범용 Stream
IntStream : 값 타입이 Int인 Stream
LongStream : 값 타입이 Long인 Stream
DoubleStream : 값 타입이 Double인 Stream
-
사용법
1). 스트림 생성
- 객체 생성
(컬렉션 객체에 stream()메서드를 호출하면 스트림 객체를 만들 수 있다.)
ex)
List<String> list = Arrays.asList("a", "b", "C");
Stream<String> stream = list.stream();
수열 형태의 형태의 데이터 생성 ex)
Stream<String> stream = Stream.iterate(1, n -> n + 1).limit(5);
// ( 1, 2, 3, 4, 5)
2). 중간연산
- 스트림을 연결할 수 있는 연산
- 중간 연산은 해당 단말 연산을 스트림 파이프라인에 실행하기 전까지는 아무 연산도 실행하지 않는다
(중간 연산을 모두 합친 다음에 합쳐진 중간 연산을 최종 연산으로 한번에 처리한다)
- 명령어
- Stream < T > distinct() : Stream 요소 중복 제거
- Stream < T > sorted() : Stream 요소 정렬
- Stream < T > filter(Predicate < T > predicate) : 조건에 충족하는 요소만 Stream생성
ex)
Stream<Integer> stream = Intstream.range(1, 10).boxed(); //1~9까지 데이터를 갖는 스트림 생성
stream.filter( n -> (n%2 ==0)) //위에서 생성한 스트림 중 짝수만 골라서 스트림 생성(2, 4, 6, 8)
.forEach(System.out::println);
- Stream < T > limit(long maxSize) : maxSize 까지의 요소를 Stream으로 생성
- Stream < T > skip(ling n) : 처음 n개의 요소를 제외하는 stream 생성
- Stream < T > peek(Consumer< T > action) : T타입 요소에 맞는 작업 수행
- Stream < R > map(Fucntion<? super T, ? extends R> mapper) : 스트림에서 나오는 데이터 변경
ex)
Stream<Integer> stream = Intstream.range(1, 10).boxed(); //1~9까지 데이터를 갖는 스트림 생성
stream.filter( n -> (n%2 ==0)) //위에서 생성한 스트림 중 짝수만 골라서 스트림 생성
.map( n -> n*10 ) //위에서 생성한 스트림 값 * 10 (20, 40, 60, 80)
.forEach(System.out::println);
- Stream < R > flatMap(Function< T, stream<? extends R>> Tmapper) : T타입 요소를 1:N의 R타입 요소로 변환하여 스트림 생성
- Stream < R > map(Function<? super T, ? extends R> mapper) : 입력 T타입을 R타입 요소로 변환한 스트림 생성
- Stream mapToInt(),mapToLong(),mapToDobule() : 만약 map Type이 숫자가 아닌 경우 변환하여 사용
3). 최종연산
(1) 통계값
sum() : 스트림 값 모두 더함
count() : 스트림 개수 구함
max() : 최대값
min() : 최소값
average() : 평균값
(2) Collect
- collect() 메서드를 이용해 스트림을 통한 데이터를 다시 컬렉션으로 바꿀 수 있다.
ex)
Stream<Integer> stream = Intstream.range(1, 10).boxed(); //1~9까지 데이터를 갖는 스트림 생성
stream.filter( n -> (n%2 ==0)) //위에서 생성한 스트림 중 짝수만 골라서 스트림 생성
.collect(Collectors.toSet()); //2, 4, 6, 8을 set컬렉션에 모아둠
- collect()메서드로 데이터를 컬렉션에 모아 둘 수 있으며 이 메서드에는 Collector 메서드를 사용할 수 있다.
- Collector 클래스에 Collector.toList()사용시 리스트로, Collector.toSet()을 호출하면 Set으로 만들어 준다.
(3) forEach
- 스트림에서 나오는 값에 어떤 작업을 하고 싶을때 forEach()메서드를 이용한다