[Java] 스트림

Local Gaji·2023년 9월 3일

이것이 자바다

목록 보기
18/18

🎈 스트림이란

다양한 구조의 데이터(List, Map 등...) 를 표준화된 방법으로 반복 처리하기 위해 만들어진 내부 반복자

병렬 처리가 가능해서 처리 속도가 빠르다
Iterator 에 for문을 쓰고 어쩌고 하는거보다 코드가 간단하다
중간 처리와 최종 처리를 하도록 파이프라인을 형성할 수 있다
다양한 요소를 표준화된 방법으로 처리할 수 있다
Stream<int> stream = list.stream();
stream.fo

Iterator 는 해당 컬렉션 바깥으로 꺼내서 사용하는 외부 반복자 이다.
stream 은 람다식을 가지고 컬렉션 내부에서 요소를 반복처리하는 내부 반복자로, 병렬 처리가 가능하다.


🎈 스트림 파이프라인

여러 스트림이 연결되는 것
오리지널 스트림 뒤에 필터링 스트림, 맵핑 스트림 등 중간 스트림을 연결하고, 그 뒤에 최종 처리 스트림을 연결할 수 있다.

  • 중간 스트림 : 필터링, 맵핑, 정렬 등의 작업을 수행
  • 최종 스트림 : 정제된 요소를 집계 (카운팅, 총합, 평균 등)

최종 스트림이 없으면 중간 스트림도 실행되지 않는다

// 예시 : 평균 구하기
double avg = scores.stream()             // 오리지널
	.mapToInt(e -> Integer.parseInt(e))  // 중간 스트림 : 맵핑
	.average().getAsDouble();            // 최종 스트림 : 평균 계산

🎈 스트림을 사용할 데이터

// 리스트 컬렉션 스트림
Stream<E> stream = list.stream();

// 배열 스트림
Stream<E> stream = Arrays.stream(arr);

// 숫자 범위 스트림
IntStream stream = IntStream.range(1,10);        // 1~9  까지
IntStream stream = IntStream.rangeClosed(1,10);  // 1~10 까지

// 해당 경로 속 파일들
Stream<Path> stream = Files.list(path);         

// 텍스트파일 한줄씩 읽기
STream<String> stream = Files.lines(path, Charset.defaultCharset());  

처리하는 요소들이 모두 정수면 IntStream, Long 이면 LongStream, Double 이면 DoubleStream 을 타입으로 지정한다.


🎈 중간 스트림


🔰 필터링


// 중복 제거
distinct()

// 조건 필터링
filter(람다식)

🔰 맵핑


map(람다식)           // 반환값 얻어서 stream 에 저장

mapToInt(람다식)      //    IntStream 으로 저장
mapToLong(람다식)     //   LongStream 으로 저장
mapToDouble(람다식)   // DoubleStream 으로 저장


flatMap(람다식)       // 반환되는 요소가 여러개일 때 (요소 쪼개기)

flatMapToInt(람다식)     
flatMapToLong(람다식)   
flatMapToDouble(람다식)

🔰 정렬

sorted()             // 요소를 정렬한 스트림 생성
sorted(Comparator)   // 정렬 기준을 Comparator 로 지정

sorted()

Comparable 객체만 sorted() 메서드로 정렬이 가능하다.
Comparable 하지 않은 객체는 비교자 Comparator 를 통해 정렬할 수 있다.

sorted((a, b) -> Integer.compare(a.getValue(), b.getValue())
// Integer.compare 메서드를 이용해 각 요소 객체의 getValue() 값을 기준으로 오름차순 정렬 

🔰 루핑 : peek

요소를 그냥 하나씩 가져와서 반복 처리한다.

peek(람다식)

peek(e -> System.out.println(e))

peek 는 중간 스트림으로 최종 스트림이 필요하다.


🎈 최종 스트림


🔰 루핑 : forEach

peek 와 동일하게 요소를 루핑하지만 forEach 는 최종 스트림이다.


🔰 매칭

요소들이 특정 조건에 만족하는지 여부를 조사해서 boolean 을 리턴한다.


boolean result = list.stream()
	.allMatch(a -> a > 10);     //    모두 10보다 큰지 조사
    
boolean result = list.stream()
	.anyMatch(a -> a > 10);     // 하나라도 10보다 큰지 조사  

🔰 집계

요소를 처리해서 하나의 값으로 산출한다.

기본 집계 메서드

메서드역할리턴 타입
count()요소 개수long
sum()요소 총 합int, long, double
findFirst()첫번째 요소Optional<T>
average()요소 평균값OptionalDouble
max()
max(Comparator)
요소 최댓값Optional<T>
min()
min(Comparator)
요소 최솟값Optional<T>

🔰 수집 : collect()

중간 처리를 한 스트림의 요소들을 수집해서 컬렉션에 담는다.

/* 리스트에 저장 */
List<E> newList = list.stream()
	.중간처리...()
    .collect(Collectors.toList()); 

/* 담을 컬렉션 지정 */
Collectors.toList()                 // 리스트에 저장
Collectors.toSet()                  // Set 에 저장
Collectors.toMap(e->, e->)       // Map 에 저장 

toMap 메서드에는 람다식을 이용해 요소로부터 키가 될 부분과 값이 될 부분을 각각 지정해준다.


🎈 병렬 스트림

포크조인 프레임워크를 사용해 요소들을 병렬 처리한다.

parallelStream()  // 컬렉션으로부터 병렬 스트림을 생성하여 리턴
parallel()        // 기존 스트림을 병렬 스트림으로 변환하여 리턴

list.parallelStream().중간스트림().최종스트림()
  • 요소의 개수가 적고 요소 당 처리 시간이 짧으면 병렬 처리가 오히려 느릴 수 있다.
  • CPU 코어 수가 적으면 병렬 처리가 오히려 느릴 수 있다.
  • Set, LinkedList 자료형은 요소 분리가 어려워 병렬 처리가 늦다.

0개의 댓글