JAVA < Stream >

Zero·2022년 4월 2일
0

스트림(Stream)

자바 8에서 추가된 스트림은 기존 자바 I/O에서 나오는 InputStream, OutputStream 과는 다른것으로 함수형 프로그램에서 단계적으로 정의된 계산을 처리하기 위한 인터페이스

  • 동일한 데이터를 가지는 배열과 리스트 선언
  • 각각 데이터 정렬을 위한 메서드를 통해 데이터를 정렬
  • 정렬된 값을 확인하기 위해 출력문을 이용해 출력

1) 기존의 방식

데이터 정렬을 위해 각각 Arrays, Collections 의 sort메서드를 이용해 정렬한 다음 for문을 이용해 결과를 출력하는 형식

2) Stream API 사용

데이터 소스(배열 혹은 리스트)로 부터 스트림을 생성하고 정렬을 위해 sorted() 메서드를 호출한다음 출력을 위해 forEach() 메서드를 호출

-> 람다(lamda)를 이용하여 출력하는 경우

스트림 연산 구조와 생성

1) 스트림 연산 구조

스트림은 어떻게가 아니라 무엇을 할것인지에 목적을 두고 사용해야 하며 연산의 파이프 라인은 스트림 생성 -> 중간연산 -> 최종연산의 형태를 가진다 이들은 .를 이용한 메서드 체이닝으로 구현 된다

  • 중복 데이터를 제거하고 , 데이터를 5개로 제한해서 정렬한 다음 출력하는 코드

Stream 생성

1) Empty Stream

비어 있는 스트림을 생성하기 위해서는 empty() 메서드를 사용

2) Array Stream

배열로부터 스트림을 생성하는 여러가지 방법

3) Collection Stream

Collection , List , Set 은 stream() 메서드와 parallelStream() 메서드를 사용할 수 있다. Map의 경우 Key 혹은 Value 값만 리스트로 추출한 다음 스트림을 만들어 사용할 수 있다

4) File Stream

파일의 경우 자바 NIO의 Files 클래스를 이용해 문자열 스트림 생성이 가능합니다

중간 연산 메서드

  • 스트림 필터링 : filter() , distinct()
  • 스트림 변환 : map() , flatMap()
  • 스트림 제한 : limit() , skip()
  • 스트림 정렬 : sorted()
  • 스트림 연산 결과 확인 : peek()
  • 타입 변환 : asDoubleStream(), asLongStream() , boxed()

1) filter(), distinct()

스트림 요소를 필터링 하기 위한 메서드

filter()는 스트림 요소 마다 비교문을 만족하는 요소로 구성된 스트림을 반환한다. 즉 , 특정 조건에 맞는 값만 추리기 위한 용도로 사용 distinct()는 요소들의 중복을 제거하고 스트림 반환

2) map()

스트림의 각 요소마다 수행할 연산을 구현할 때 사용

3) flatMap()

기존의 요소를 새로운 요소로 대체한 스트림을 생성

4) limit()

스트림의 시작 요소로 부터 인자로 전달된 인덱스 까지의 요소를 추출해 새로운 스트림을 생성

5) skip()

스트림의 시작 요소로 부터 인자로 전달된 인덱스 까지를 제외하고 새로운 스트림 생성

6) sorted()

스트림 요소를 정렬하는 메서드로 기본적으로 오름차순 정렬

  • 두번째와 세번째 방법은 오름차순 구현을 활용해 내림차순으로 처리할 때 사용
  • 내림차순 정렬을 위한 또 다른 방법은 -a.compareTo(b)를 사용하는 것인데 직관적이지 못해 권장 x

또 다른 방법은 Comparator를 사용하는 것으로 새로운 정렬 조건을 지정하고자 한다면 sorted((a,b) -> {} ) 와 같이 코드를 작성

7) peek()

결과 스트림의 요소를 사용해 추가로 동작 수행

  • 스트림 연산 과정에서 중간 중간 결과를 확인할 때 사용

최종 연산 메서드

  • 요소의 출력 : forEach()
  • 요소의 소모 : reduce()
  • 요소의 검색 : findFirst(), findAny()
  • 요소의 검사 : anyMatch(), allMatch(), noneMatch()
  • 요소의 통계 : count(), min() , max()
  • 요소의 연산 : sum() , average()
  • 요소의 수집 : collect()

1) forEach()

스트림의 요소들을 순환하면서 반복해서 처리해야 하는 경우 사용

2) reduce()

map()과 비슷하게 동작하지만 개별연산이 아니라 누적연산이 이루어진다는 차이
ex) 두개의 인자 즉 n, n+1을 가지며 연산결과는 n이 되고 다시 다음 요소와 연산을 하게 된다 즉 1,2번째 요소를 연산하고 그 결과와 3번째 요소를 연산하는 식

3) findFirst(), findAny()

두 메서드는 스트림에서 지정한 첫번째 요소를 찾는 메서드

보통 filter() 와 함께 사용되고 findAny() 는 parallelStream() 에서 병렬 처리 시 가장 먼저 발견된 요소를 찾는 메서드로 결과는 스트림 원소의 정렬 순서와 상관 x

  • findAny() 를 parallelStream()과 함께 사용하는 경우 일반적으로 findFirst()와 결과가 같다

  • parallelStream() 과 사용한 경우 실제 스트림 순서와는 다르게 선택될 수 있다

  • findFirst()와 findAny()의 리턴 값은 Optional이므로 ifPresent()를 이용해 출력

4) anyMatch(), allMatch(), noneMatch()

스트림의 요소 중 특정 조건을 만족하는 요소를 검사하는 메서드

원소중 일부 , 전체 혹은 일치하는 것이 없는 경우를 검사하고 boolean 값을 리턴
noneMatch() 의 경우 일치하는 것이 하나도 없을 때 true

5) count(), min(), max()

스트림의 원소들로 부터 전체 개수, 최소값, 최대값을 구하기 위한 메서드

min() , max()의 경우 Comparator 를 인자로 요구하고 있으므로 기본 Comparator들을 사용하거나 직접 람다 표현식으로 구분해야 함

6) sum() , average()

스트림 원소들의 합계를 구하거나 평균을 구하는 메서드

reduce() 와 map()을 이용해도 구현이 가능 , 리턴값이 Optional이기 때문에 ifPresent() 를 이용해 값을 출력할 수 있다

7) Collect()

스트림의 결과를 모으기 위한 메서드로 Collectors 객체에 구현된 방법에 따라 처리하는 메서드

  • 스트림을 배열이나 컬렉션으로 변환 : toArray(), toCollection(), toList(), toSet(), toMap()
  • 요소의 통계와 연산 메소드와 같은 동작을 수행 : counting(), maxBy(), minBy(), summingInt(), averagingInt() 등
  • 요소의 소모와 같은 동작을 수행 : reducing(), joinning()
  • 요소의 그룹화와 분할 : groupingBy(), partitioningBy()

  • toMap() 을 사용해서 문자열 스트림의 값을 키로 하고 문자열의 길이를 값으로 하는 맵으로 변환.

  • counting, maxBy, reducing 은 각각 count(), max(), reduce() 메서드와 동일한 결과.

  • summarizingInt 는 IntSummaryStatistics 를 리턴하며 count, sum, min, average, max 값을 참조할 수 있음.

  • groupingBy는 특정 조건에 따라 데이터를 구분해서 저장.

  • partitioningBy는 특정 조건으로 데이터를 두그룹으로 나누어 저장.

0개의 댓글