카테고리 없음

#9 스트림

kmsoon 2024. 5. 10. 15:56

스트림이란?

스트림은 데이터 소스를 추상화하고, 데이터를 다루는데 자주 사용되는 메서드들을 정의해 놓았다. 스트림을 이용하면 배열이나 컬렉션뿐만 아니라 파일에 저장된 데이터도 모두 같은 방식으로 다룰 수 있다.
 

스트림 특징

 
스트림은 데이터 소스를 변경하지 않는다.
 
스트림은 데이터 소스로부터 데이터를 읽기만할 뿐, 변경하지 않는다.
 
스트림은 일회용이다.
 
스트림은 Iterator처럼 일회용이다. 한 번 사용하면 닫혀서 사용할 수 없다.
 
필요 시 다시 생성하거나, 결과를 컬렉션이나 배열에 담아두고 사용할 수 있다.
 
스트림은 작업을 내부 반복으로 처리한다.
 
내부 반복을 통해 간결한 코드를 작성할 수 있다.
 

스트림의 사용방법

 
스트림 생성 : 데이터 소스로부터 스트림을 생성
 
중간 연산 : 원하는 형태로 데이터를 가공, 연속해서 연결할 수 있다.
 
최종 연산 : 원하는 형태로 반환
 
중간 연산
중간 연산
설명
Stream<T> distinct()
중복을 제거
Stream<T> filter()
조건에 안 맞는 요소 제외
Stream<T> limit()
스트림의 일부를 잘라낸다.
Stream<T> skip()
스트림의 일부를 건너뛴다.
Stream<T> peek()
스트림의 요소에 작업수행
Stream<T> sorted()
스트림의 요소를 정렬
Stream<R> map() DoubleStream mapToDouble() IntStream mapToInt() LongStream mapToLong()
스트림의 요소를 변환
Stream<R> flatMap() DoubleStream flatMapToDouble() IntStream flatMapToInt() LongStream flatMapToLong()
스트림의 요소를 변환
 
최종 연산
최종 연산
설명
void forEach() void forEachOrdered()
각 요소에 지정된 작업을 수행
long count()
스트림의 요소의 개수 반환
Optional<T> max() Optional<T> min()
스트림의 최대값/최소값 반환
Optional<T> findAny() // 아무거나 하나 Optional<T> findFirst() // 첫 번째 요소
스트림의 요소 하나를 반환
boolean allMatch() // 모두 만족 boolean anyMatch() // 하나라도 만족 boolean noneMatch() // 모두 만족x
주어진 조건을 모든 요소가 만족시키는지, 만족시키지 않는지 확인
Object[] toArray()
스트림의 모든 요소를 배열로 반환
Optional<T> reduce()
스트림의 요소를 하나씩 줄여가면서 계산
R collect()
스트림의 요소를 수집한다. 주로 요소를 그룹화하거나 분할한 결과를 컬렉션에 담아 반환하는데 사용된다.
 

병렬 스트림

병렬 스트림은 내부적으로 fork&join 프레임워크를 이용해서 자동적으로 연산을 병렬로 수행한다.
 
parallel() : 병렬로 연산을 수행하도록 지시
 
sequential() : 병렬로 처리되지 않게 한다.

 

parallel()과 sequential()은 새로운 스트림을 생성하는 것이 아니라, 스트림의 속성을 변경할 뿐이다.
 

스트림 요소 걸러내기 - filter(), distinct()

filter()는 매개변수로 Predicate를 필요로 하는데, 연산결과가 boolean인 람다식을 사용해도 된다.

 

 

 

정렬 - sorted()

문자열 스트림 정렬 방법
정렬 방법
출력 결과
sorted() // 기본정렬 sorted(Comparator.naturalOrder()) // 기본정렬 sorted((s1, s2)→s1.compareTo(s2)) // 람다식도 가능 sorted(String::compareTo)
CCaaabccdd
sorted(Comparator.reverseOrder()) // 기본정렬 역순 sorted(Comparator.<String>naturalOrder().reversed())
ddccbaaaCC
sorted(String.CASE_INSENSITIVE_ORDER) // 대소문자 구분x
aaabCCccdd
sorted(String.CASE_INSENSITIVE_ORDER.reversed())
ddCCccbaaa
sorted(Comparator.comparing(String::length)) // 길이 순 정렬 sorted(Comparator.comparingInt(String::length)) // no오토박싱
bddCCccaaa
sorted(Comparator.comparing(String::length).reversed())
aaaddCCccb
 

스트림 최종 연산

forEach()

 
스트림의 요소를 출력하는 용도로 사용되는 최종 연산이다.

조건 검사 - allMatch(), anyMatch(), noneMatch(), findFirst(), findAny()

 
모두 매개변수로 predicate를 요구하며, 연산결과로 boolean을 반환한다.

통계 - count(), sum(), average(), max(), min()

 

스트림의 변환

스트림 → 기본형 스트림

from
to
변환 메서드
Stream<T>
IntStream LongStream DoubleStream
mapToInt(Function<T> mapper) mapToLong(Function<T> mapper) mapToDouble(Function<T> mapper)

기본형 스트림 → 스트림

from
to
변환 메서드
IntStream LongStream DoubleStream
Stream<Integer> Stream<Long> Stream<Double>
boxed()
 
Stream<U>
mapToObj(Function<U> mapper)

기본형 스트림 → 스트림

from
to
변환 메서드
IntStream LongStream DoubleStream
LongStream DoubleStream
asLongStream() asDoubleStream()

스트림 → 부분 스트림

from
to
변환 메서드
Stream<T> IntStream
Stream<T> IntStream
skip(long n) limit(long maxSize)

두 개의 스트림 → 스트림

from
to
변환 메서드
Stream<T>
Stream<T>
concat(Stream<T> a, Stream<T> b)
IntStream
IntStream
concat(IntStream a, IntStream b)
LongStream
LongStream
concat(LongStream a, LongStream b)
DoubleStream
DoubleStream
concat(DoubleStream a, DoubleStream b)

스트림의 스트림 → 스트림

from
to
변환 메서드
Stream<Stream<T>>
Stream<T>
flatMap(Function mapper)
Stream<IntStream>
IntStream
flatMapToInt(Function mapper)
Stream<LongStream>
LongStream
flatMapToLong(Function mapper)
Stream<DoubleStream>
DoubleStream
flatMapToDouble(Function mapper)

스트림 → 병렬 스트림

from
to
변환 메서드
Stream<T>
Stream<T>
parallel() // 스트림 → 병렬 스트림
IntStream
IntStream
sequential() // 병렬 스트림 → 스트림
LongStream
LongStream
 
DoubleStream
DoubleStream
 

스트림 → 컬렉션

from
to
변환 메서드
Stream<T> IntStream LongStream DoubleStream
Collection<T> List<T> Set<T>
collect(Collectors.toCollection(Supplierfactory)) collect(Collertors.toList()) collect(Collectors.toSet())

컬렉션 → 스트림

from
to
변환 메서드
Collection<T>, List<T>, Set<T>
Stream<T>
stream()

스트림 → Map

from
to
변환 메서드
Stream<T> IntStream LongStream DoubleStream
Map<K, V>
collect(Collectors.toMap(Function key, Function value)) collect(Collectors.toMap(Function k, Function v, BinaryOperator)) collect(Collectors.toMap(Function k, Function v, BinaryOperator merge, Suppller mapSuppller))

스트림 → 배열

from
to
변환 메서드
Stream<T>
Object[] T[]
toArray() toArray(IntFunction<A[]> generator)
IntStream LongStream DoubleStream
int[] long[] double[]
toArray()