4.1 스트림 소개
: 자바 애플리케이션의 대부분은 컬렉션을 만들고 처리하는 과정을 포함
: 컬렉션으로 데이터를 그룹화 하고 처리할 수 있음
: 많은 요소를 포함하는 커다란 컬렉션의 경우 성능을 높이려면 멀티코어 아키텍처를 활용해서 병렬로 컬렉션의 요소를 처리해야한다. => 어렵고 복잡함
이를 해결하기 위한 : 스트림 등장!
스트림이란?
자바 8 API에 추가된 새로운 기능
스트림은 데이터 컬렉션 반복을 멋지고 간편하게 처리하는 기능
멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있음.
p136
기존의 코드와 자바 8비교 소스 코드 (.stream() / .parallelStream())
스트림과 파라렐 스트림은 (멀티코어 아키텍쳐에서 병렬로 실행할 수 있음)
스트림의 장점
: 람다식을 사용해서 선언형 코드로 구형할수 있다(요구사항에 쉽게 대응 가능, 간단한 코드로 코드 작성 가능)
: filter, sorted, map, collect 같은 여러 빌딩 블록 연산을 연산해서 복잡한 데이터 처리 파이프라인을 만들 수 있다.
=> 한방에 여러 연산 가능 p138 그림 4-1 참고
결과적으로 데이터 처리과정을 병렬화 하면서 스레드와 락을 걱정할 필요가 없어짐.
1. 선언형 : 더 간결하고 가독성이 좋아짐
2. 조립가능 : 유연성이 좋음
3. 병렬화 : 성능이 좋아짐
컬렉션을 제어하는 기타 라이브러리 : 구아바, 아파치, 람다제이
4.2 스트림 시작하기
자바 8 컬렉션에는 스트림을 반환 하는 stream 메서드가 추가됨(java.util.stream.Stream 참고)
스트림이란 정확히 뭘까?
: 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소
연속된 요소?
: 컬렉션과 마찬가지로 스트림은 특정 요소 형식으로 이루어진 연속된 값 집합의 인터페이스를 제공.
컬렉션은 자료구조라 arraylist나 linkedlist를 사용에 댜한 시공간 복잡성과 관련 요소 저장 및 접근 연산이 주를 이룸 (데이터)
스트림은 filter, sorted, map 처럼 표현 계산식이 주를 이룸 (계산식)
소스?
: 정렬된 컬렉션으로 스트림을 생성하면 정렬이 그대로 유지됨. 리스트로 스트림을 만들면 스트림의 요소는 리스트의 요소와 같은 순서를 유지한다.(?)
데이터 처리연산?
: filter, map, reduce, find, match, sort 등으로 데이터를 조작할 수 있음.
: 순차적으로 또는 병렬로 실행 할 수 있음
스트림의 중요 특징
1. 파이프라이닝(pipelining)
: 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프 라인을 구성할 수 있도록 스트림 자신을 반환함.
: laziness, short-circuiting 같은 최적화도 얻을 수 있음
: 연산 파이프라인은 데이터 소스에 적용하는 데이터베이스 쿼리랑 비슷함.
2. 내부반복
: 반복자를 이용해서 명시적으로 반복하는 컬렉션과 달리 스트림은 내부 반복을 지원함.
예제) p142 예시
stream 객체 생성 => 필요한 연산 처리(filter, 추출, limit) => list 형태로 반환
4.3 스트림과 컬렉션
데이터를 언제 계산하느냐가 가장 큰 차이.
컬렉션은 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 구조 => 컬렉션의 모든 요소는 컬렉션에 추가하기 전에 계산되어야함
스트림은 요청할 때만 요소를 계산하는 고정된 자료구조.
4.3.1 딱 한번만 탐색할 수 있다.
반복자와 마찬가지로 스트림도 한번만 탐색할 수 있다.
4.3.2 외부반복과 내부반복
외부반복 : 사용자가 직접 요소를 반복하는것(예를 들면 for-each). 병렬성을 스스로 관리해야함
내부반복 : 반복을 알아서 처리하고 결과 스트림값을 어딘가에 저장해줌. 최적화 가능(병렬성 구현을 자동으로 선택함)
=> 자바8에서 컬렉션 인터페이스와 비슷하면서 반복자가 없는 무엇이 필요했다! => 이것이 스트림
예제 p149
4.4 스트림 연산
- 중간 연산
: filter, map, limit은 서로 연결되어 파이프라인을 형성한다.
: 중간 연산은 다른 스트림을 반환한다.
: 여러 중간 연산을 연결해서 질의를 만들 수 있다.
: 중간 연산을 합친 다음에 합쳐진 중간 연산을 최종 연산으로 한번에 처리하기 때문 (게.으.름)
: filter, map, limit, sort, distict (p153 표참조)
- 최종 연산
: collect로 파이프라인을 실행한 다음에 닫음 (.collect(toList()));
: 스트림 파이프라인에서 결과를 도출한다.
: foreach, count, collect (p153 표참조)
4.4.3 스트림 이용하기
- 질의를 수행할 (컬렉션 같은) 데이터 소스
- 스트림 파이프라인을 구성할 중간 연산 연결
- 스트림 파이프라인을 실행하고 결과를 만들 최종연산
'개발공부 > JAVA' 카테고리의 다른 글
모던 자바인 액션 1장 (0) | 2022.08.23 |
---|---|
[인프런강의] 더 자바, 자바8 : 2강 (0) | 2022.08.21 |
Spring Initializr로 Spring Boot 프로젝트 생성하는 방법 (0) | 2022.08.21 |
[인프런강의] 더 자바, 자바8 1강 (0) | 2022.08.20 |
[JAVA] Jsoup 사용하여 네이버 주가 크롤링 (소스포함) (7) | 2021.07.13 |