0 또는 다수의 중개 오퍼레이션 (intermediate operation)과 한 개의 종료 오퍼레이션 (terminal operation)으로 구성한다.
스트림의 데이터 소스는 오직 종료 오퍼레이션을 실행할 때에만 처리한다.
중개 오퍼레이션
Stream을 리턴한다.
Stateless / Stateful 오퍼레이션으로 더 상세하게 구분할 수도 있다.
대부분은 Stateless지만 distinct나 sorted처럼 이전 소스 데이터를 참조해야 하는 오퍼레이션은 Stateful 오퍼레이션이다.
filter , map , limit , skip , sorted , ...
종료 오퍼레이션
Stream을 리턴하지 않는다.
collect , allMatch , count , forEach , min , max , ...
List<String> names = new ArrayList<>();
names.add("jeong");
names.add("park");
names.add("baek");
names.add("kim");
names.add("lee");
// Stream<String> strStream = names.stream().map(s -> s.toUpperCase());
Stream<String> strStream = names.stream().map(String::toUpperCase);
// 대문자로 변경된 데이터는 strStream에 담겨 있다.
strStream.forEach(System.out::println);
System.out.println("=============================");
// names 의 데이터가 변경 되지 않은걸 볼 수 있다.
names.forEach(System.out::println);
// 출력
// JEONG
// PARK
// BAEK
// KIM
// LEE
// =============================
// jeong
// park
// baek
// kim
// lee
List<String> names = new ArrayList<>();
names.add("jeong");
names.add("park");
names.add("baek");
names.add("kim");
names.add("lee");
// 출력 되지 않는다.
// 종료형 오퍼레이터가 실행 되기 전에는 중개형 오퍼레이터는 실행 하지 않는다.
// (단지 정의만 한것이다.)
names.stream().map((s) ->{
System.out.println("종료형 오퍼래이터가 붙지 않았을 때 : " + s);
return s.toUpperCase();
});
// 종료형 오퍼레이터 (collect)가 붙었을 때
List<String> collect = names.stream().map((s) ->{
System.out.println("종료형 오퍼래이터가 붙었을 때 : " + s);
return s.toUpperCase();
}).collect(Collectors.toList());
// 출력
// 종료형 오퍼래이터가 붙었을 때 : jeong
// 종료형 오퍼래이터가 붙었을 때 : park
// 종료형 오퍼래이터가 붙었을 때 : baek
// 종료형 오퍼래이터가 붙었을 때 : kim
// 종료형 오퍼래이터가 붙었을 때 : lee
종료형 오퍼레이터는 없지만 인스턴스가 사용될 때
List<String> names = new ArrayList<>();
names.add("jeong");
names.add("park");
names.add("baek");
names.add("kim");
names.add("lee");
Stream<Object> collect3 = names.stream().map((s) ->{
System.out.println("종료형 오퍼래이터가 붙지 않고 , 인스턴스가 사용되지 않을 때: " + s);
return s.toUpperCase();
});
Stream<Object> collect4 = names.stream().map((s) ->{
System.out.println("종료형 오퍼래이터가 붙지 않고 , 인스턴스가 사용될 때 : " + s);
return s.toUpperCase();
});
collect4.forEach(System.out::println);
// 출력
// 종료형 오퍼래이터가 붙지 않고 , 인스턴스가 사용될 때 : jeong
// JEONG
// 종료형 오퍼래이터가 붙지 않고 , 인스턴스가 사용될 때 : park
// PARK
// 종료형 오퍼래이터가 붙지 않고 , 인스턴스가 사용될 때 : baek
// BAEK
// 종료형 오퍼래이터가 붙지 않고 , 인스턴스가 사용될 때 : kim
// KIM
// 종료형 오퍼래이터가 붙지 않고 , 인스턴스가 사용될 때 : lee
// LEE
인스턴스가 사용되지 않는 collect3은 중개형 오퍼레이터가 실행되지 않는다.
인스턴스가 사용되는 collect4는 중개형 오퍼레이터가 실행 되지만 출력 순서가 조금 이상하다.
collect4의 forEach안에서 중개형 오퍼레이터를 실행하여 sout을 찍고 , forEach의 sout을 찍는 것 같다.
List<String> names = new ArrayList<>();
names.add("jeong");
names.add("park");
names.add("baek");
names.add("kim");
names.add("lee");
List<String> collectTest = names.stream().map((s) -> {
System.out.println("stream 처리 : " + s + " " + Thread.currentThread().getName());
return s.toUpperCase();
}).collect(Collectors.toList());
// 병렬 처리
// (spliterator의 trySplit을 사용하여 쪼개서 처리한다.)
List<String> collectTest2 = names.parallelStream().map((s) -> {
System.out.println("parallelStream 처리 : " + s + " " + Thread.currentThread().getName());
return s.toUpperCase();
}).collect(Collectors.toList());
// 출력
// stream 처리 : jeong main
// stream 처리 : park main
// stream 처리 : baek main
// stream 처리 : kim main
// stream 처리 : lee main
// parallelStream 처리 : baek main
// parallelStream 처리 : lee ForkJoinPool.commonPool-worker-3
// parallelStream 처리 : park ForkJoinPool.commonPool-worker-5
// parallelStream 처리 : kim ForkJoinPool.commonPool-worker-3
// parallelStream 처리 : jeong ForkJoinPool.commonPool-worker-5
[JAVA8] Stream
Stream 소개
스트림 파이프라인
중개 오퍼레이션
종료 오퍼레이션
종료형 오퍼레이터는 없지만 인스턴스가 사용될 때
참고
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
더 자바, Java 8 - 인프런
자바 8에 추가된 기능들은 자바가 제공하는 API는 물론이고 스프링 같은 제 3의 라이브러리 및 프레임워크에서도 널리 사용되고 있습니다. 이 시대의 자바 개발자라면 반드시 알아야 합니다. 이
www.inflearn.com
'기록 > JAVA' 카테고리의 다른 글