개발새발
#스트림 본문
Stream — 스트림
- 배열, 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 반복자
- List, Set, Map배열 등 다양한 데이터 소스로부터 스트림을 만들 수 있고, 다룰 수 있다
- 병렬 스트림을 사용하기 위해서는 스트림의 parallel()메서드를 사용
List list = Arrays.asList(1,2,3,4,5);
Stream intStream = list.stream(); //컬렉션
Stream strStream = Stream.of(new String\[\] {“a”, “b”, “c”}); // 배열
Stream evenStream = Stream.iterate(0, n->n+2); // 0,2,4,6
Stream randomStream = Stream.generate(Math :: random); // 람다식
IntStream intStream = new Random().ints(5); // 난수 스트림(크기가 5)
특징
- 선언형으로 데이터 소스를 처리할 수 있다
- 선언형 프로그래밍이랑 ‘어떻게’ 수행하는지보다 ‘무엇을’ 수행하는지에 관심을 둔다
- 선언형 방식으로 코드를 작성하면 내부 동작 원리를 모르더라고 코드가 무슨 일을 하는지 이해할 수 있다
파이프라인 구성(.)
리덕션(Reduction) - 대량의 데이터를 가공해서 축소하는 것
- 테이터의 합계, 평균값, 카운팅, 최대값, 최소값 등이 대표적
- 그러나 컬렉션의 요소를 리덕션의 결과물로 바로 집계할 수 없을 때에는 필터링, 매핑, 정렬, 그룹핑등의 중간 연산이 필요
파이프라인
- 데이터의 필터링, 매핑, 정렬, 그루핑 등의 중간 연산과 합계, 평균, 카운팅, 최대 / 최소값 등의 최종 연산을 파이프라인(pipelines)으로 해결
- 여러개의 스트림이 연결되어 있는 구조를 의미
스트림 생성, 중간연산, 최종연산
스트림 생성
- Collection 인터페이스에는 stream()이 정의되어 있기 때문에, Collection 인터페이스를 구현한 객체들(List, Set 등)은 모두 이 메서드를 이용해 스트림을 생성할 수 있다
- stream()을 사용하면 해당 Collection의 객체를 소스로 하는 Stream을 반환
- 데이터 소스로부터 데이터를읽기만 할 뿐 변경하지 않는다
- 일회용으로, 한 번 사용하면 닫히므로, 필요할때 마다 새로운 스트림을 만들어야 함
// List로부터 스트림을 생성 List list = Arrays.asList("a", "b", "c"); Stream listStream = list.stream(); listStream.forEach(System.out::prinln); //스트림의 모든 요소를 출력.
// 배열로부터 스트림을 생성
Stream stream = Stream.of("a", "b", "c"); //가변인자
Stream stream = Stream.of(new String[] {"a", "b", "c"});
Stream stream = Arrays.stream(new String[] {"a", "b", "c"});
Stream stream = Arrays.stream(new String[] {"a", "b", "c"}, 0, 3); //end 범위 미포함
// 4이상 10미만의 숫자를 갖는 IntStream
IntStream stream = IntStream.range(4, 10);
리턴 타입 메서드(매개 변수) 소스
Stream java.util.Collection.Stream(), java.util.Collection.parallelSream( ) 컬렉션
Stream, IntStream, LongStream, DoubleStream Arrays.stream(T[]), Arrays.stream(int[]), Arrays.stream(long[]), Arrays.stream(double[]), Stream.of(T[]), IntStream.of(int[]) LongStream.of(long[]), DoubleStream.of(double[]) 배열
IntStream IntStream.range(int, int), IntStream.rangeClosed(int, int) int 범위
LongStream LongStream.range(long, long), LongStream.rangeClosed(long, long) long 범위
중간연산
- 연산 결과를 스트림으로 반환하기 때문에, 여러번 수행 가능
필터링
- distinct() : Stream의 요소들에 중복된 데이터가 존재하는 경우, 중복을 제거하기 위해 사용
- filter() : Stream에서 조건에 맞는 데이터만을 정제하여 더 작은 컬렉션을 만들고, filter() 메서드에는 매개값으로 조건(Predicate)이 주어지고, 조건이 참이 되는 요소만 필터링
- 인텔리제이
매핑
- map() : 기존의 stream 요소들을 대체하느 요소로 구성된 새로운 stream을 형성
- 저장된 값을 특정한 형태로 변환하는데 주로 사용
- map 함수의 인자로 함수형 인터페이스 function을 받고 있다
- map()이외에도 mapToInt(), mapToLong(), mapToDouble() 등의 메서드가 있다
- flatMap(): flatMap은 요소를 대체하는 복수 개의 요소들로 구성된 새로운 스트림을 리턴
- flatMap()과 map()의 차이점은, map()은 스트림의 스트림을 반환하는 반면, flatMap()은 스트림을 반환한다
연산 결과 확인
\= peek()
- peek은 중간 연산이므로 하나의 스트림에 여러 번 사용할 수 있다
intStream
.filter(a -> a%2 ==0)
.peek(n-> System.out.println(n))
.sum();
```
최종 연산
- 연산 결과 확인 (forEach())
- 최종 연산 메서드이므로 파이프라인 마지막에서 요소를 하나씩 연산
- 값을 출력할 때도 사용하지만, 이메일 발송, 스케줄링등 리턴 값이 없는 작업에서도 많이 사용
매칭(match())
stream의 요소들이 특정한 조건을 충족하는지 검사하고 싶은 경우 사용
함수형 인터페이스 Predicate를 받아서 해당 조건을 만족하는 검사, 검사 결과를 boolean으로 반황
allMatch() : 모든 요소들이 매개값으로 주어진 Predicate의 조건을 만족하는지 조사
anyMatch() : 최소한 한 개의 요소가 매개값으로 주어진 Predicate의 조건을 만족하는지 조사
noneMatch() : 모든 요소들이 매개값으로 주어진 Predicate의 조건을 만족하지 않는지 조사
Reduce
- Sum,average,count,max,min 외에도 다양한 집계 결과물을 만들 수 있는 메서드
- 누적하면서 하나로 응축하는 방식으로 동작
reduce 메서드는 최대 3개의 매개변수를 받을 수 있다
- Accumulator: 각 요소를 계산한 중간 결과를 생성하기 위해 사용
- Identity: 계산을 수행하기 위한 초기값
- Combiner: 병렬 스트림(Parlallel Stream)에서 나누어 계산된 결과를 하나로 합치기 위한 로직
Collect()
- Stream의 요소들을 List,Set,Map등 다른 종류의 결과로 수집하고 싶은 경우에 사용
'자바' 카테고리의 다른 글
#InputStream, OutputStream #Thread(스레드) #Multi-thread(멀티 스레드) (0) | 2022.08.03 |
---|---|
#JSON (0) | 2022.08.03 |
#enum #애노테이션 (0) | 2022.07.27 |
# 내부 클래스 (0) | 2022.07.27 |
#제네릭 #컬렉션 프레임워크 (0) | 2022.07.27 |