백엔드/Java

[Java] 스트림(Stream)

2023. 5. 11. 01:15
목차
  1. 스트림(Stream)이란?
  2. 딱 한 번만 탐색할 수 있다.
  3. 외부 반복과 내부 반복
  4. 스트림 연산
728x90

스트림(Stream)이란?

스트림(Stream)은 자바8 API에 새로 추가된 기능이다.

스트림을 이용하면 선언형으로 컬렉션 데이터를 처리할 수 있다.

또한 스트림을 이용하면 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있다.

 

스트림은 소프트웨어 공학적으로 다음의 다양한 이득을 준다.

  • 선언형으로 코드를 구현할 수 있다.
    • 루프와 if 조건문 등의 제어 블록을 사용해서 어떻게 동작을 구현할지 지정할 필요 없이 '저칼로리의 요리만 선택하라' 같은 동작의 수행을 지정할 수 있다.
  • filter, sorted, map, collect 같은 여러 빌딩 블록 연산을 연결해서 복잡한 데이터 처리 파이프라인을 만들 수 있다.
    • 여러 연산을 파이프라인으로 연결해도 여전히 가독성과 명확성이 유지된다.
    • 고수준 빌딩 블록으로 이루어져 있으므로 특정 스레딩 모델에 제한되지 않고 자유롭게 어떤 상황에서든 사용할 수 있다.
    • 결과적으로 우리는 데이터 처리 과정을 병렬화하면서 스레드와 락을 걱정할 필요가 없다.


딱 한 번만 탐색할 수 있다.

반복자(for-each와 같은)와 마찬가지로 스트림도 한 번만 탐색할 수 있다. 즉, 탐색됨 스트림의 요소는 소비된다.

한 번 탐색한 요소를 다시 탐색하려면 초기 데이터 소스에서 새로운 스트림을 만들어야 한다.(그러려면 컬렉션처럼 반복 사용할 수 있는 데이터 소스여야 한다. 만일 데이터 소스가 I/O 채널이라면 소스를 반복 사용할 수 없으므로 새로운 스트림을 만들 수 없다.)


외부 반복과 내부 반복

컬렉션 인터페이스를 사용하려면 사용자가 직접 요소를 반복해야 한다.(예를 들면 for-each 등을 사용해서) 이를 외부 반복(external iteration)이라고 한다.

반면 스트림 라이브러리는 (반복을 알아서 처리하고 결과 스트림값을 어딘가에 저장해주는) 내부 반복(internal iteration)을 사용 한다.

 

for-each 루프를 이용하는 외부 반복

List<String> names = new ArrayList<>();
for(Dish: menu) {
	names.add(dish.getName());
}

 

스트림 : 내부 반복

List<String> names = menu.stream()
					.map(Dish::getName)
                  .collect(toList());

 

내부 반복이 외부 반복보다 좋은 이유

  • 투명하게 병렬로 처리하고 더 최적화된 다양한 순서로 처리할 수 있다.
  • 외부 반복에서는 병렬성을 스스로 관리해야 한다.

스트림 연산

스트림 인터페이스의 연산은 크게 두 가지로 구분할 수 있다.

  • 중간 연산 : 여러 중간 연산을 연결해서 질의를 만들 수 있다. 단말 연산을 스트림 파이프라인에 실행하기 전까지는 아무 연산도 수행하지 않는다. 즉, Lazy 하다. 중간 연산을 합친 다음에 합쳐진 중간 연산을 최종 연산으로 한 번에 처리한다.
  • 최종 연산 : 스트림 파이프라인에서 결과를 도출한다. 보통 최종 연산에 의해 List, Integer, void 등 스트림 이외의 결과가 반환된다.

다음은 누가 중간 연산이고 누가 최종 연산인지 요약해서 보여준다.

 

중간 연산

연산 형식 반환 형식 연산의 인수 함수 디스크립터
filter 중간 연산 Stream<T> Predicate<T> T -> boolean
map 중간 연산 Stream<T> 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 최종 연산   스트림을 리듀스해서 리스트, 맵, 정수 형식의 컬렉션을 만든다.

 

 


참고 자료 : 

https://ebook-product.kyobobook.co.kr/dig/epd/ebook/E000002942391

 

모던 자바 인 액션 | 라울-게이브리얼 우르마 | 한빛미디어- 교보ebook

람다, 스트림, 함수형, 리액티브 프로그래밍으로 새로워진 자바 마스터하기, ★ 완전히 새로워진 자바 8, 9, 10의 기능을 속 시원하게 배우자! 이 책은 자바 최신 기능을 애플리케이션에 실용적으

ebook-product.kyobobook.co.kr

 

'백엔드 > Java' 카테고리의 다른 글

[Java] 전략 패턴(Strategy Pattern)  (0) 2023.05.17
[Java] 템플릿 메서드 패턴(Template Method Pattern)  (0) 2023.05.17
[Java] 람다(Lambda)  (0) 2023.05.09
[Java] 동작 파라미터화(Behavior Parameterization)  (0) 2023.05.09
[Java] 런타임 데이터 영역 (Runtime Data Area)  (0) 2023.05.05
  1. 스트림(Stream)이란?
  2. 딱 한 번만 탐색할 수 있다.
  3. 외부 반복과 내부 반복
  4. 스트림 연산
'백엔드/Java' 카테고리의 다른 글
  • [Java] 전략 패턴(Strategy Pattern)
  • [Java] 템플릿 메서드 패턴(Template Method Pattern)
  • [Java] 람다(Lambda)
  • [Java] 동작 파라미터화(Behavior Parameterization)
밝은별 개발자
밝은별 개발자
호기심 가득한 밤을 하나씩 밝히는 밝은별입니다.
밝은별 개발자
밝은별 개발 블로그
밝은별 개발자
전체
오늘
어제
  • 전체 글 (59)
    • 자소서 (0)
    • 백엔드 (55)
      • Java (15)
      • 네트워크 (5)
      • JPA (11)
      • Spring (6)
      • 운영체제 (8)
      • MSA (4)
      • etc (4)
      • 데이터베이스 (2)
    • 프로젝트 (3)
      • Petogram (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • JPA
  • Petogram
  • db
  • 디자인 패턴
  • Service discovery
  • Spring
  • 쓰기 지연
  • 메모리
  • 이펙티브자바
  • 런타임데이터영역
  • 변경 감지
  • 상속
  • 객체지향
  • JDK 동적프록시
  • Java
  • HTTP
  • 캐시
  • Redis
  • 데이터베이스
  • OS
  • 클린 아키텍처 #spring
  • EUREKA
  • ORM
  • 네트워크
  • java8
  • 운영체제
  • 영속성컨텍스트
  • 스트림
  • pojo
  • MSA

최근 댓글

최근 글

hELLO · Designed By 정상우.
밝은별 개발자
[Java] 스트림(Stream)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.