SlideShare a Scribd company logo
Stream API
자바카페
김흥래
스트림
• 컬렉션은 자바에서 가장 많이 사용하는 기
능이다. (Collections Framework)
• 대부분의 어플리케이션은 컬렉션을 만들
고 컬렉션 데이터를 처리하는 과정을 반복
한다.
• Java8에서는 컬렉션 데이터를 처리하기 위
한 Stream API가 추가되었다.
스트림
• 스트림은 컬렉션 데이터를 처리하는 코드를 선언형으로 구현
할 수 있다.
• 제어문(for, while, if)을 이용하여 컬렉션 데이터가 어떻게 동
작을 해야 하는지 일일이 코딩 할 필요없이 ‘어떤 동작을 수행
하라’는 형태의 선언만으로 컬렉션 데이터를 가공할 수 있다.
• SQL과 비슷한 형태이다.
– Select * from user where age > 10;
– 위와 같이 단순한 선언문만으로 디스크의 정보를 가공하여 가져
올 수 있다.
– 프로그래머가 직업 제어문을 이용하여 row나 column 데이터를
어떻게 가공할 지 코딩하지 않는다.
– 연산 과정은 전적으로 DB Optimizer에게 위임하고 결과에만 관
심이 있다.
스트림
• Stream API는 filter, sort, map, collect 같은 빌딩 블록 연산을
제공한다.
• 여러 블록 연산을 연결하여 파이프라인을 구현하는 것이 가능
하다. (Divide & Conquer)
• 고수준의 블록 연산을 제공하여 특정 스레드 모델에 제한되지
않고 멀티코어 아키텍처를 투명하게 활용할 수 있다.
• 병렬처리시 스레드와 락을 고민하지 않아도 된다.
• 스트림이란 데이터 처리 연산을 지원하도록 소스에서 추출된
연속된 요소
3. stream api
스트림 vs 컬렉션
• 컬렉션과 스트림 모두 연속된 요소 형식의 값을 저
장하는 자료구조의 인터페이스를 제공한다.
• 둘다 순서에 따라 순차적으로 요소에 접근한다.
• 컬렉션과 스트림의 가장 큰 차이는 데이터를 언제
계산하느냐 이다.
– 컬렉션 : 요소를 접근하면서 계산식을 만날때마다 계
산이 일어난다.
– 스트림 : 최종연산을 요청할 때만 계산한다.
데이터 접근 측면
• 컬렉션
– 자료구조이므로 데이터에 접근, 읽기, 변경, 저장 같
은 연산이 주요 관심사이다. (직접 데이터 핸들링)
– 데이터에 접근하는 방법을 직접 작성해야 한다.
• 스트림
– Filter, sorted, map 처럼 계산식(람다)을 표현하는
것이 주요 관심사이다. (계산식을 JVM으로 던진다.)
– 데이터에 접근하는 방법이 추상화 되어 있다.
데이터 계산 측면
• 컬렉션
– 작업을 위해서 Iterator로 모든 요소를 순환해야 한다.
– 메모리에 모든 요소가 올라간다. (OOM)
– 모든 요소가 메모리에 올라가 있는 상태에서 요소를 누적
시키며 결과를 계산한다.
– 메모리 사용량 연산속도
• 스트림
– 계산식(알고리즘 or 람다)을 미리 적어두고 계산시에 람다
로 JVM에 넘긴다.
– 내부에서 요소를 어떻게 메모리에 올리는 지는 관심사가
아니다. (블랙박스)
– 계산 요청시 결과가 바로 리턴된다.
– 메모리 사용량 연산속도
스트림 연산
• 스트림은 2가지로 연산이 구분된다.
– Filter, map, limit는 서로 연결되어 파이프라인
을 형성한다.
– Collect로 마지막 파이프라인을 수행후 완료한
다.
• 중간연산 (Intermediate Operation)
• 최종연산 (Terminal Operation)
filter map limit collect
중간연산 최종연산
Menu.stream().filter(d -> d.getCalories() > 300)
.map(Dish::getName)
.limit(3)
.collect(toList());
중간연산은 파이프라인으로 연결되어
선언식이 최종연산으로 전달된다.
중간연산 정보를 스트림으로 입력받
아 최종연산에서 한번에 처리한다.
단말 연산을 스트림 파이프라인에 실행하기 전까지는 아무 연산도 수행하지 않는다. (Lazy)
모든 중간연산을 합친 다음 최종연산에서 한번에 처리한다.
필터링과 슬라이싱
• 스트림의 요소를 선택하는 방법을 블록 연산
으로 제공
• 주요 API
// Predicate와 일치하는 데이터만 Stream으로 반환
Stream<T> filter(Predicate<? super T> predicate);
// Stream 데이터 중복제거 (hashcode & equals)
Stream<T> distinct();
// Stream 데이터 축소 (Cut)
Stream<T> limit(long maxSize);
// Stream 데이터 건너뛰기
Stream<T> skip(long n);
3. stream api
3. stream api
3. stream api
매핑
• 스트림의 특정 객체에서 원하는 데이터만
선택하는 작업을 블록 연산으로 제공
• 주요 API
// 데이터의 람다식 결과가 새로운 Stream으로 제공
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
// 람다식 결과가 새로운 Stream으로 제공되는 것은 동일
// 만약 결과가 여러개의 스트림(Stream<Object[]>)일때
하나의 스트림으로 변환
<R> Stream<R>
flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
3. stream api
3. stream api
3. stream api
3. stream api
검색과 매칭
• 특정 속성이 데이터 집합에 존재하는지 여부를 검색하
는 기능을 블록 연산으로 제공
• 주요 API
// Predicate가 하나라도 일치하는지 검사
boolean anyMatch(Predicate<? super T> predicate);
// Predicate가 모두 일치하는지 검사
boolean allMatch(Predicate<? super T> predicate);
// Predicate가 모두 불일치하는지 검사
boolean noneMatch(Predicate<? super T> predicate);
// Stream에서 아무 데이터나 Optional로 리턴
Optional<T> findAny();
// Stream에서 첫번째 데이터를 Optional로 리턴 (병렬 실행시 성능이슈)
Optional<T> findFirst();
3. stream api
3. stream api
3. stream api
리듀싱
• 스트림의 요소를 누적하여 어떠한 연산을
하는 기능을 블록 연산으로 제공
• 주요 API
// 초기값 T를 기준으로 연산을 누적시켜 결과를 제공
T reduce(T identity, BinaryOperator<T> accumulator);
// 초기값 없이 연산을 누적시켜 Optional로 리턴 (Max, Min)
Optional<T> reduce(BinaryOperator<T> accumulator);
long count();
3. stream api
Quiz
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
3. stream api
기본형 특화 스트림
• Java8에서 3가지 기본형(Primitive) 특화 스트림을 제공한다.
– IntStream
– DoubleStream
– LongStream
• 기존 스트림을 특화 스트림으로 변화
IntStream mapToInt(ToIntFunction<? super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
LongStream mapToLong(ToLongFunction<? super T> mapper);
• 특화 스트림을 객체 스트림으로 복원
Stream<Integer> boxed();
Stream<Double> boxed();
Stream<Long> boxed();
• 특정범위의 숫자를 스트림으로 생성
// 시작값과 종료값 미포함
public static IntStream range(int startInclusive, int endExclusive) {}
// 시작값과 종료값 포함
public static IntStream rangeClosed(int startInclusive, int endInclusive) {}
AutoBoxing 비용
캐스팅 비용이 겁나 비싸다!!!
3. stream api
3. stream api
스트림 만들기
• 스트림을 일반적으로 컬렉션에서 생성하지만 직접 스트림을
생성하는 것도 가능하다.
• 주요 API
// 문자열로 스트림 생성
public static<T> Stream<T> of(T t) {}
// 배열로 스트림 생성
public static <T> Stream<T> stream(T[] array) {}
// 무한스트림 생성 (초기값이 존재, 내부에서 연산이 누적된다.)
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {}
// 무한스트림 생성 (초기값이 미존재, 외부에서 연산을 가져온다.)
public static<T> Stream<T> generate(Supplier<T> s) {}
3. stream api
스트림 만들기
• 무한스트림 생성시 주의점
– 성능을 고려하여 항상 limit() 연산자와 함께 사용해야 한다.
– Generate를 사용할 경우 병렬코드에 주의해야 한다.
• Stream.iterator
– 단항연산자 타입을 인수로 받는다.
– 기준값을 가지고 있으므로 내부에서 누적시키면서 연산하
므로 병렬 코드에 안전하다.
• Stream.generate
– 공급자 타입을 인수로 받는다.
– 특정 객체가 누적 연산을 하도록 위임하므로 병렬 코드에
안전 여부를 반드시 확인해야 한다.
(공급된 객체가 반드시 불변객체여야 한다.)
3. stream api

More Related Content

PPTX
1. introduction to java8
PDF
엘라스틱서치 클러스터로 수십억 건의 데이터 운영하기
PDF
자바8 스트림 API 소개
PDF
Java8 & Lambda
PDF
자바8강의 2강. Stream API
PDF
발표자료 11장
PDF
자바8강의 0강. java8 overview
PDF
Ji 개발 리뷰 (신림프로그래머)
1. introduction to java8
엘라스틱서치 클러스터로 수십억 건의 데이터 운영하기
자바8 스트림 API 소개
Java8 & Lambda
자바8강의 2강. Stream API
발표자료 11장
자바8강의 0강. java8 overview
Ji 개발 리뷰 (신림프로그래머)

What's hot (20)

PDF
자바8강의 1강. lambda expression
PPTX
자바 8 학습
PPTX
UML distilled 1장 스터디 발표 자료
PPTX
Just java
PPTX
Java8 람다
PDF
동시성 프로그래밍 하기 좋은 Clojure
PDF
자바8 람다식 소개
PDF
3주차. stream api advance
PDF
Pair RDD - Spark
PDF
Java 8 api :: lambda 이용하기
PDF
5 swift 기초함수
PDF
JDK 변천사
PDF
7가지 동시성 모델 - 데이터 병렬성
PPTX
자바 8
PDF
9 swift 클로저1
PDF
Lambda 란 무엇인가
PDF
씹고 뜯고 맛보고 즐기는 스트림 API
PDF
자바8 람다 나머지 공개
PDF
모델링 연습 리뷰
PDF
[143] Modern C++ 무조건 써야 해?
자바8강의 1강. lambda expression
자바 8 학습
UML distilled 1장 스터디 발표 자료
Just java
Java8 람다
동시성 프로그래밍 하기 좋은 Clojure
자바8 람다식 소개
3주차. stream api advance
Pair RDD - Spark
Java 8 api :: lambda 이용하기
5 swift 기초함수
JDK 변천사
7가지 동시성 모델 - 데이터 병렬성
자바 8
9 swift 클로저1
Lambda 란 무엇인가
씹고 뜯고 맛보고 즐기는 스트림 API
자바8 람다 나머지 공개
모델링 연습 리뷰
[143] Modern C++ 무조건 써야 해?
Ad

Viewers also liked (20)

PDF
java lang
PDF
[2012 자바카페 OPEN 세미나] Introduction to google guava
PPTX
2. lambda expression
PDF
Java 자료구조 비교 (Java1.6 기준)
PPTX
이것이 자바다 Chap.11 기본 API 클래스(java)(KOR)
PDF
Spring boot와 docker를 이용한 msa
PPT
Java API, Exceptions and IO
PDF
Java 강의자료 ed11
PDF
Spring으로 콩 심기
PDF
Spring 3.1에서 ehcache 활용 전략
PPTX
[DevOn 2013] Dynamic web proxy
PPTX
ORM을 활용할 경우의 설계, 개발 과정
PDF
자바 8 스트림 API
PPTX
자바9 특징 (Java9 Features)
PDF
주키퍼
PPTX
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
PDF
Elastic stack
PPTX
영속성 컨텍스트로 보는 JPA
PDF
초보자를 위한 정규 표현식 가이드 (자바스크립트 기준)
PDF
컴퓨터 프로그램 구조와 해석 3.5
java lang
[2012 자바카페 OPEN 세미나] Introduction to google guava
2. lambda expression
Java 자료구조 비교 (Java1.6 기준)
이것이 자바다 Chap.11 기본 API 클래스(java)(KOR)
Spring boot와 docker를 이용한 msa
Java API, Exceptions and IO
Java 강의자료 ed11
Spring으로 콩 심기
Spring 3.1에서 ehcache 활용 전략
[DevOn 2013] Dynamic web proxy
ORM을 활용할 경우의 설계, 개발 과정
자바 8 스트림 API
자바9 특징 (Java9 Features)
주키퍼
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
Elastic stack
영속성 컨텍스트로 보는 JPA
초보자를 위한 정규 표현식 가이드 (자바스크립트 기준)
컴퓨터 프로그램 구조와 해석 3.5
Ad

Similar to 3. stream api (20)

PDF
람다, 스트림 Api
PPTX
스트림Api 스터디 2일
PPTX
스트림Api 소개
PDF
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 씹고 뜯고 맛보고 즐기는 스트림 API(박용권)
PPTX
(망작)이것이 자바다 Chap.16 스트림&병렬처리 Stream&parallel processing(java)
PPTX
스트림Api 스터디 3일
PDF
Java(4/4)
PDF
Java stream v0.1
PDF
Java stream v0.1
PPTX
조리돌림 JAVA8 기반의 기능.pptx
PPTX
[자바카페] 람다 아키텍처, 더 깊이 살펴보기
PDF
데이터폭발시대의실시간데이터분석
PPTX
Hybrid & Logical Data Warehouse
PDF
스사모 테크톡 - Apache Flink 둘러보기
PPTX
Apache kafka 확장과 응용
PPTX
Java collections framework
PDF
진큐 오버뷰
PPTX
Feel functional
PDF
[236] 카카오의데이터파이프라인 윤도영
PPTX
Spark streaming tutorial
람다, 스트림 Api
스트림Api 스터디 2일
스트림Api 소개
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 씹고 뜯고 맛보고 즐기는 스트림 API(박용권)
(망작)이것이 자바다 Chap.16 스트림&병렬처리 Stream&parallel processing(java)
스트림Api 스터디 3일
Java(4/4)
Java stream v0.1
Java stream v0.1
조리돌림 JAVA8 기반의 기능.pptx
[자바카페] 람다 아키텍처, 더 깊이 살펴보기
데이터폭발시대의실시간데이터분석
Hybrid & Logical Data Warehouse
스사모 테크톡 - Apache Flink 둘러보기
Apache kafka 확장과 응용
Java collections framework
진큐 오버뷰
Feel functional
[236] 카카오의데이터파이프라인 윤도영
Spark streaming tutorial

More from 흥래 김 (13)

PPTX
생초보를 위한 한글 형태소 분석하기
PPTX
검색엔진과 DB Like 검색의 결과가 다른 이유
PPTX
Elasticsearch와 Python을 이용하여 맨땅에서 데이터 분석하기
PDF
한글 자동완성 구현하기
PDF
한글 자모 분석 원리
PDF
한글 형태소 분석기 활용하기
PPTX
Spring di chapter2
PPTX
Spring di chapter1
PPTX
5강 코드효율성
PDF
[제14회 JCO 컨퍼런스] 개발자를 위한 서버이중화 by JAVACAFE
PPTX
Apache http component
PPTX
플랫폼 통합을 위한 Client Module 개발 & 배포
PPTX
[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화
생초보를 위한 한글 형태소 분석하기
검색엔진과 DB Like 검색의 결과가 다른 이유
Elasticsearch와 Python을 이용하여 맨땅에서 데이터 분석하기
한글 자동완성 구현하기
한글 자모 분석 원리
한글 형태소 분석기 활용하기
Spring di chapter2
Spring di chapter1
5강 코드효율성
[제14회 JCO 컨퍼런스] 개발자를 위한 서버이중화 by JAVACAFE
Apache http component
플랫폼 통합을 위한 Client Module 개발 & 배포
[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화

3. stream api

  • 2. 스트림 • 컬렉션은 자바에서 가장 많이 사용하는 기 능이다. (Collections Framework) • 대부분의 어플리케이션은 컬렉션을 만들 고 컬렉션 데이터를 처리하는 과정을 반복 한다. • Java8에서는 컬렉션 데이터를 처리하기 위 한 Stream API가 추가되었다.
  • 3. 스트림 • 스트림은 컬렉션 데이터를 처리하는 코드를 선언형으로 구현 할 수 있다. • 제어문(for, while, if)을 이용하여 컬렉션 데이터가 어떻게 동 작을 해야 하는지 일일이 코딩 할 필요없이 ‘어떤 동작을 수행 하라’는 형태의 선언만으로 컬렉션 데이터를 가공할 수 있다. • SQL과 비슷한 형태이다. – Select * from user where age > 10; – 위와 같이 단순한 선언문만으로 디스크의 정보를 가공하여 가져 올 수 있다. – 프로그래머가 직업 제어문을 이용하여 row나 column 데이터를 어떻게 가공할 지 코딩하지 않는다. – 연산 과정은 전적으로 DB Optimizer에게 위임하고 결과에만 관 심이 있다.
  • 4. 스트림 • Stream API는 filter, sort, map, collect 같은 빌딩 블록 연산을 제공한다. • 여러 블록 연산을 연결하여 파이프라인을 구현하는 것이 가능 하다. (Divide & Conquer) • 고수준의 블록 연산을 제공하여 특정 스레드 모델에 제한되지 않고 멀티코어 아키텍처를 투명하게 활용할 수 있다. • 병렬처리시 스레드와 락을 고민하지 않아도 된다. • 스트림이란 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소
  • 6. 스트림 vs 컬렉션 • 컬렉션과 스트림 모두 연속된 요소 형식의 값을 저 장하는 자료구조의 인터페이스를 제공한다. • 둘다 순서에 따라 순차적으로 요소에 접근한다. • 컬렉션과 스트림의 가장 큰 차이는 데이터를 언제 계산하느냐 이다. – 컬렉션 : 요소를 접근하면서 계산식을 만날때마다 계 산이 일어난다. – 스트림 : 최종연산을 요청할 때만 계산한다.
  • 7. 데이터 접근 측면 • 컬렉션 – 자료구조이므로 데이터에 접근, 읽기, 변경, 저장 같 은 연산이 주요 관심사이다. (직접 데이터 핸들링) – 데이터에 접근하는 방법을 직접 작성해야 한다. • 스트림 – Filter, sorted, map 처럼 계산식(람다)을 표현하는 것이 주요 관심사이다. (계산식을 JVM으로 던진다.) – 데이터에 접근하는 방법이 추상화 되어 있다.
  • 8. 데이터 계산 측면 • 컬렉션 – 작업을 위해서 Iterator로 모든 요소를 순환해야 한다. – 메모리에 모든 요소가 올라간다. (OOM) – 모든 요소가 메모리에 올라가 있는 상태에서 요소를 누적 시키며 결과를 계산한다. – 메모리 사용량 연산속도 • 스트림 – 계산식(알고리즘 or 람다)을 미리 적어두고 계산시에 람다 로 JVM에 넘긴다. – 내부에서 요소를 어떻게 메모리에 올리는 지는 관심사가 아니다. (블랙박스) – 계산 요청시 결과가 바로 리턴된다. – 메모리 사용량 연산속도
  • 9. 스트림 연산 • 스트림은 2가지로 연산이 구분된다. – Filter, map, limit는 서로 연결되어 파이프라인 을 형성한다. – Collect로 마지막 파이프라인을 수행후 완료한 다. • 중간연산 (Intermediate Operation) • 최종연산 (Terminal Operation)
  • 10. filter map limit collect 중간연산 최종연산 Menu.stream().filter(d -> d.getCalories() > 300) .map(Dish::getName) .limit(3) .collect(toList()); 중간연산은 파이프라인으로 연결되어 선언식이 최종연산으로 전달된다. 중간연산 정보를 스트림으로 입력받 아 최종연산에서 한번에 처리한다. 단말 연산을 스트림 파이프라인에 실행하기 전까지는 아무 연산도 수행하지 않는다. (Lazy) 모든 중간연산을 합친 다음 최종연산에서 한번에 처리한다.
  • 11. 필터링과 슬라이싱 • 스트림의 요소를 선택하는 방법을 블록 연산 으로 제공 • 주요 API // Predicate와 일치하는 데이터만 Stream으로 반환 Stream<T> filter(Predicate<? super T> predicate); // Stream 데이터 중복제거 (hashcode & equals) Stream<T> distinct(); // Stream 데이터 축소 (Cut) Stream<T> limit(long maxSize); // Stream 데이터 건너뛰기 Stream<T> skip(long n);
  • 15. 매핑 • 스트림의 특정 객체에서 원하는 데이터만 선택하는 작업을 블록 연산으로 제공 • 주요 API // 데이터의 람다식 결과가 새로운 Stream으로 제공 <R> Stream<R> map(Function<? super T, ? extends R> mapper); // 람다식 결과가 새로운 Stream으로 제공되는 것은 동일 // 만약 결과가 여러개의 스트림(Stream<Object[]>)일때 하나의 스트림으로 변환 <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
  • 20. 검색과 매칭 • 특정 속성이 데이터 집합에 존재하는지 여부를 검색하 는 기능을 블록 연산으로 제공 • 주요 API // Predicate가 하나라도 일치하는지 검사 boolean anyMatch(Predicate<? super T> predicate); // Predicate가 모두 일치하는지 검사 boolean allMatch(Predicate<? super T> predicate); // Predicate가 모두 불일치하는지 검사 boolean noneMatch(Predicate<? super T> predicate); // Stream에서 아무 데이터나 Optional로 리턴 Optional<T> findAny(); // Stream에서 첫번째 데이터를 Optional로 리턴 (병렬 실행시 성능이슈) Optional<T> findFirst();
  • 24. 리듀싱 • 스트림의 요소를 누적하여 어떠한 연산을 하는 기능을 블록 연산으로 제공 • 주요 API // 초기값 T를 기준으로 연산을 누적시켜 결과를 제공 T reduce(T identity, BinaryOperator<T> accumulator); // 초기값 없이 연산을 누적시켜 Optional로 리턴 (Max, Min) Optional<T> reduce(BinaryOperator<T> accumulator); long count();
  • 26. Quiz
  • 41. 기본형 특화 스트림 • Java8에서 3가지 기본형(Primitive) 특화 스트림을 제공한다. – IntStream – DoubleStream – LongStream • 기존 스트림을 특화 스트림으로 변화 IntStream mapToInt(ToIntFunction<? super T> mapper); DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper); LongStream mapToLong(ToLongFunction<? super T> mapper); • 특화 스트림을 객체 스트림으로 복원 Stream<Integer> boxed(); Stream<Double> boxed(); Stream<Long> boxed(); • 특정범위의 숫자를 스트림으로 생성 // 시작값과 종료값 미포함 public static IntStream range(int startInclusive, int endExclusive) {} // 시작값과 종료값 포함 public static IntStream rangeClosed(int startInclusive, int endInclusive) {}
  • 45. 스트림 만들기 • 스트림을 일반적으로 컬렉션에서 생성하지만 직접 스트림을 생성하는 것도 가능하다. • 주요 API // 문자열로 스트림 생성 public static<T> Stream<T> of(T t) {} // 배열로 스트림 생성 public static <T> Stream<T> stream(T[] array) {} // 무한스트림 생성 (초기값이 존재, 내부에서 연산이 누적된다.) public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {} // 무한스트림 생성 (초기값이 미존재, 외부에서 연산을 가져온다.) public static<T> Stream<T> generate(Supplier<T> s) {}
  • 47. 스트림 만들기 • 무한스트림 생성시 주의점 – 성능을 고려하여 항상 limit() 연산자와 함께 사용해야 한다. – Generate를 사용할 경우 병렬코드에 주의해야 한다. • Stream.iterator – 단항연산자 타입을 인수로 받는다. – 기준값을 가지고 있으므로 내부에서 누적시키면서 연산하 므로 병렬 코드에 안전하다. • Stream.generate – 공급자 타입을 인수로 받는다. – 특정 객체가 누적 연산을 하도록 위임하므로 병렬 코드에 안전 여부를 반드시 확인해야 한다. (공급된 객체가 반드시 불변객체여야 한다.)