JAVA 8 : 스트림 기본

600g (Kim Dong Geun)·2021년 4월 4일
1

스트림

  • 스트림은 Java 8 API 에 새로 추가된 기능

  • 선언형으로 컬렉션 데이터를 처리할 수 있음

  • 멀티쓰레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리가능

  • filter, sorted, map, collect 같은 여러 빌딩 블록 연산을 연결해서 복잡한 데이터 처리 파이프 라인을 만들 수 있음.

  • 즉 스트림의 키워드를 정리하자면 다음과 같다. 선언형, 조립, 병렬화

스트림이란?

  • 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소 // 뭔뜻이야 이게...

연속된 요소

  • 컬렉션과 마찬가지로 스트림은 특정 요소 형식으로 이루어진 연속된 값 집합의 인터페이스를 제공한다.

소스

  • 스트림은 컬렉션, 배열, I/O 자원 등의 데이터 제공 소스로부터 데이터를 소비한다.
  • 정렬된 컬렉션으로 스트림을 생성하면 정렬이 그대로 유지된다.

데이터 처리 연산

  • 스트림은 함수형 프로그래밍 언어에서 일반적으로 지원하는 연산과 데이터베이스와 비슷한 연산을 지원한다.
  • filter,map,reduce,find,match,sort 등으로 데이터를 조작할 수 있다.

파이프라이닝

  • 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프 라인을 구성할 수 있도록 스트림 자신을 반환한다.
  • 그 덕분에 Lazyness, short-circuiting 과 같은 최적화도 얻을 수 있다.

내부 반복

  • 반복자를 이용해서 명시적으로 반복하는 컬렉션과 달리 스트림은 내부 반복을 지원한다.

스트림은 filter,map,limit,collect로 이어지는 일련의 데이터 처리 연산을 적용.

collect 를 제외한 모든 연산은 서로 파이프라인을 형성할 수 있도록 스트림을 반환한다.

마지막으로 collect 연산으로 파이프라인을 처리해서 결과를 반환한다. 마지막에 collect가 호출되기 전까지는 메소드 호출이 저장되는 효과가 있다.

스트림 연산자들

  1. filter : 람다를 인수로 받아 스트림에서 특정 요소를 제외시킨다.
  2. map : 람다를 이용해서 한 요소를 다른 요소로 변환하거나 정보를 추출한다.
  3. limit : 정해진 개수 이상의 요소가 스트림에 저장되지 못하게 스트림 크기를 축소 truncate 한다.
  4. collect : 스트림을 다른 형식으로 반환한다.

스트림과 컬렉션

  • 스트림과 컬렉션의 가장 큰 차이는 데이터를 언제 계산 하느냐가 가장 큰 차이점이다.

  • 컬렉션은 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 자료구조다. 즉 컬렉션의 모든 요소는 컬렉션에 추가하기 전에 계산되어져야 한다.

  • 반면 스트림은 이론적으로 요청할때만 요소를 계산하는 고정된 자료구조다.

  • 결과적으로 스트림은 생산자와 소비자의 관계를 형성한다.

딱 한 번만 계산할 수 있다.

  • 반복자(Iterator)와 마찬가지로 스트림도 한 번만 탐색할 수 있다.
  • 즉, 탐색된 스트림의 요소는 소비된다. (반복자와 마찬가지로 한 번 탐색한 요소를 다시 탐색하려면 초기 데이터 소스에서 새로운 스트림을 만들어야 한다.)

스트림과 컬렉션의 철학적으로 생각해보자면?

스트림은 시간적으로 흩어진 값의 집합으로 간주할 수 있다.

반면 컬렉션은 특정시간에 모든 것이 존재하는 공간에 흩어진 값으로 비유할 수 있다.

외부반복과 내부반복

  • 컬렉션 인터페이스를 사용하려면 사용자가 직접 요소를 반복해야 한다. 이를 외부 반복이라 한다.
  • 스트림 라이브러리는 반복을 알아서 처리하고 결과 스트림값을 어딘가에 저장해주는 내부 반복 이라한다.
외부반복내부반복
투명성XO
병렬처리어려움(직접 관리)쉬움(자동 처리)

스트림 연산

  • 스트림 인터페이스의 연산을 크게 두 가지로 구분할 수 있다.
  • filter,map,limit 은 서로 연결되어 파이프라인을 형성한다. 이를 중간 연산이라한다.
  • collect 로 파이프라인을 실행한 다음에 닫는다. 스트림을 닫는 연산을 최종 연산 이라고 한다.

중간연산

  • filtersorted 같은 중간 연산은 다른 스트림을 반환한다.

  • 중간 연산의 가장 중요한 특징은 단말 연산을 스트림 파이프라인에 실행하기전 까지는 아무 연산도 수행하지 않는다는 것

  • = Lazy한 연산.

  • 이런 스트림의 특성 덕에 몇가지 최적효과를 얻을 수 있다. => short circit

Short Circuit이란? 연산을 모두 수행하지 않고 검색 조건을 만족했을시, 즉시 이후 연산을 종료하고 결과를 반환하는 기법

최종연산

  • 최종 연산은 스트림 파이프라인에서 결과를 도출한다. 보통 최종 연산에 의해 List, Integer, void 등 스트림 이외의 결과반환

정리

  • 중간연산
연산형식반환형식연산의 인수함수 디스크립터
filter중간 연산Stream<T>Predicate<T>T -> boolean
map중간 연산Stream<R>Function<T,R>T -> R
limit중간 연산Stream<T>
sorted중간 연산Stream<T>Comparator<T>(T,T)-> int
distinct중간 연산Stream<T>
  • 최종연산
연산형식반환 형식목적
forEach최종 연산void스트림의 각 요소를 소비하면서 람다를 적용한다.
count최종 연산Long(generic)스트림의 요소 개수를 반환한다.
collect최종연산스트림을 리듀스해서 리스트, 맵, 정수형식의 컬렉션을 만든다.
profile
수동적인 과신과 행운이 아닌, 능동적인 노력과 치열함

0개의 댓글