코딩항해기

[리뷰/우아한테크] Stream (Java api) 본문

IT tech

[리뷰/우아한테크] Stream (Java api)

miniBcake 2024. 7. 1. 13:58

 

프로그래머스에서 문제를 풀고 나서 다른 답안을 보니 Stream을 사용한 답안들이 많아

Stream에 대해 알아보고자 관련 영상을 시청 후 기록을 남기게 되었다.

 

오늘 볼 영상은 우아한 테크의 [10분 테코톡] 차리의 Stream이다.

Stream 영상이 더 있었는데, 가장 기초 내용인 것 같아 해당 영상으로 시청하게 되었다.

 

 

 


 

Stream 스트림

어떠한 요소들이 모인 하나의 고정된 집합이라고 생각하기보다 데이터 흐름(flow)으로 이해하는 것이 좋다.
자바의 스트림 API는 이 데이터들을 어떻게 다룰 것인가를 논하는 일종의 파이프라인으로 볼 수 있다.

 


Stream의 구조

생성 source
*스트림 인스턴스 생성
list, map과 같은 컬렉션
Array(배열)
File
Infinite(무한)
Third-party (별도의 서드파티 라이브러리) 등
가공 (Intermediate Operation)
*필터링 및 맵핑 등 원하는 결과값을 만들어 내기 위한 과정
filter
map
peek
sorted
distinct
limit 등
(루프퓨전/쇼트서킷 테크닉 활용가능)
(stateless 와 statefull로 구분할 수 있다.)
소비 (Terminal Operation)
*최종적으로 결과를 만들어내는 작업
collect (class Collectors를 활용하면 더 좋다)
findAny
findFirst
anyMatch
allMatch
forEach 등

 

*루프 퓨전

모든 요소가 각 단계를 한 번에 거치는 것이 아니라,

개별적인 요소가 하나씩 단계를 순차적으로 거쳐가는 모습이

반복문이 합쳐진 것과 유사하여 루프퓨전이라고 칭한다.

 

*쇼트 서킷

일련의 논리연산을 진행할 때 결과가 확실한 경우

나머지 연산을 수행하지 않는 것을 의미한다.

ex) if(num==0 || num <=0) 이 때 num==0이 true라면 num<=0을 확인하지 않는 것

 

*stateless (독립적)

특정 행위를 수행할 때 다른 요소에 대해서 독립적으로 처리될 수 있음을 의미한다.

ex. map 등

 

*statefull (종속적)

선행된 연산에 영향을 받는다.

이 연산자가 실행되려면 자기 자신 이외의 값은 무엇이었는지 등의 특정상태를 알아야한다.

ex. sorted, distinct 등

 


소비단계의 주의점

1. 최종 연산자가 수행되고 나면 스트림 파이프라인은 소비된 것으로 간주한다.

    => 다시 사용하려면 새로운 스트림을 만들어야한다.

    (IllegalStateException : stream has already been opeated upon or closed ...)

 

2. for each와 같이 사이드 이펙트를 통해서만 동작할 수 있는 연산은 신중하여야 한다.

 

*forEach는 로그나 디버깅용도로만 사용할 것을 권장한다.

-> 불필요한 사이드 이펙트를 만들어내고 병렬처리시 올바른 값을 기대하기 힘들다.

=> collect로 대체 가능하기 때문에 굳이 사용할 필요가 없다.

 


Stream 사용의 장단점

장점

1. 가독성이 좋다.

2. 코드 변경이 쉽다. (유연하다)

3. 병렬처리가 쉽다. (parallel() / parallelStream() 포크조인 프레임워크 활용)

 

단점

1. 높은 컴퓨팅 비용

   (Stream은 내부적으로 다양한 조건과 상황에 따라서 연산을 처리하기 때문)

 

2. 인지에 대한 비용

   (외부반복은 중간 값을 확인할 수 있는 방면,

    스트림은 내부반복이기 때문에 내부에서 문제가 생긴다면 이를 알기 어려움)

 

외부반복, 내부반복 설명 이미지(왼쪽이 외부반복, 오른쪽이 내부반복이다)