정리
스트림과 컬렉션의 차이가 뭘까?
사실 회사에서 스트림을 쓰고 있는데 사용하면서도 이게 컬렉션보다 보기 편하고 쓰기 편하군ㅇㅇ 이정도 감상이었는데 이번에 확실히 감이 잡히더라
스트림 시작
여기서 제일 인상깊었고, 컬렉션과의 차이에 대해 쉽게 접근할 수 있었던게, 컬렉션의 주제는 데이터고 스트림의 주제는 계산 이라는 점이었다.
말하자면 컬렉션은 요소 저장 및 접근, 스트림은 그걸 가지고 계산하는 것이 주가 된다는 것이다.
그리고 스트림이 가진 두가지 중요 특징이
- 파이프라이닝
- 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프라인을 구성할 수 있도록 스트림 자신을 반환함
- lazy(결과값이 필요할 때에 계산하도록... 그니까 알아서 스트림의 중간/최종 연산을 통해 안쓸거는 안쓰게 하는 최적화 같은 느낌이다)이랑 short circuit(불필요한 연산을 수행하지 않도록 하는것이고 말하자면
limit
과 같은 연산을 통해 다른 요소들에의 연산 자체를 생략하는것)
- lazy(결과값이 필요할 때에 계산하도록... 그니까 알아서 스트림의 중간/최종 연산을 통해 안쓸거는 안쓰게 하는 최적화 같은 느낌이다)이랑 short circuit(불필요한 연산을 수행하지 않도록 하는것이고 말하자면
- 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프라인을 구성할 수 있도록 스트림 자신을 반환함
- 내부 반복
- 이후 설명이 나올것같기는 한데, 외부에서 명령을 주는게 아니라 스스로 처리하는것
스트림과 컬렉션
스트림은 알다시피 순차적으로 값에 접근한다(연속되어)
비교하자면
- 컬렉션
- 동영상 파일
- 스트림
- 인터넷 스트리밍
이다.
그니까 컬렉션은 이걸 통해서 뭔가를 처리하기 위해서는 전체를 다 가지고 있어야 하고, 스트림은 원하는 때에 추출하는 것이다.
그래서 이제 소수를 쭈르르르륵 만든다면 스트림은 원하는 값만 추출하고 컬렉션은 계속 계산을 하고 있어서 확인할 수 없게 되는 것이다.
또 다른 차이점은 스트림은 한번만 소비할 수 있다는 것이다.
외부 반복과 내부 반복
아까 나왔던건데, 컬렉션의 사용방법과 스트림의 사용방법에도 차이가 있더라...
이전에 컬렉션은 for문같은거를 돌면서 내부에서 조건을 통해 처리하거나 뭔가 역할을 끼워넣어서 진행하고는 했다.
근데 그게 외부 반복
이었던 것이다...
사용자가 원하는 것을 하기 위해 컬렉션을 돌리면서 명령을 주는 것이다.
예를 들면 가방에서 동그란거를 찾아서 바구니에 넣으려고 하면
- Q: 지금 가방에 뭐가 있냐
- A: 네모난거 있다.
- Q: 그건 버려
- A: ㅇㅇ
- Q: 지금 가방에 뭐가 있냐
- A: 세모난거 있다.
- Q: 그건 버려
- A: ㅇㅇ
- Q: 지금 가방에 뭐가 있냐
- A: 동그란거 있다.
- Q: 그건 바구니에 넣어
- A: ㅇㅇ
대충 이런 식으로, 꺼내봐 -> ㅇㅇ -> 이게 뭐야 -> 이거임 -> 이거 어떻게 처리해 어쩌고
이런 느낌으로다가 명시적으로 처리하는거다.
스트림을 쓰는 내부 반복
의 경우는 내가 직접 처리하는거니까
- 일단 바구니 앞으로 가서
- 가방에 있는거를 함 봐서
- 동그란거를 바구니에 넣어야지~
할 수 있는 것이다.
이를 통해 작업의 투명성, 최적화된 순서, 병렬성 구현을 할 수 있다.
여기서 병렬성이라는게... 외부 반복에서는 처리할 때에 다른 곳에서 가방에 접근을 막기 위해 synchronized
같은걸 써야하는데 스트림은 그럴 필요가 없는것이라고 한다.
스트림 연산
이전에 공부했던것에서 중간 연산이랑 최종 연산에 대해 적어 두었는데, 여기서 그거의 연산을 굳이 두개로 구분짓는 이유가 나와있다.
중간 연산
중간 연산은 다른 스트림을 반환한다.
-> 그래서 이걸로 여러개를 통해 하나의 스트림을 질의를 만들 수 있다.
그리고 중간연산의 특징은 최종 연산으로 한번에 수행한다는 것인데, 이를 통해 최종에 필요한 애들만 lazy
하게 가져온다.<- 최적화 가능
이 책의 코드에서 되게 잘 설명해 주었는데 앞의 연산들에 대해 최종 연산 limit
이 있으면, 이 최종 연산에 필요한 애들만이 수행되는 것이다.
이걸 해주는게 상술한 쇼트 서킷이고, 여러 다른 연산을 하나의 과정으로 병합하는 루프 퓨전이 가능해진다.
최종 연산
이거를 하면서 실제로 결과를 도출해준다.
-> 그래서 이걸 통해 결과 타입이 정해진다.
정리하면서
공부하는 방법을 좀 바꿔 보았다.
여기서 얘기했던 것처럼 그냥 앵무새처럼 따라하기보다는 내가 이해한 내용을 토대로 이래이래 했더라~ 라고 하려고 했는데 사실 지금은 그래도 따라한것 같기는 하지만 이해한것을 적으려고 하니까 확실히 시간도 적게 쓰이고 공부도 더 잘되는것 같기도 하고??
암튼 그리고 요즘 모던자바를 쓰면서 스트림을 잘 쓰려고 하는데, 이게 쓰기는 쉽고 쓰니까 좋긴 좋네ㅇㅇ 싶었는데 여기서 장점에 대해 잘 알게되어 좋았다.
확실히 자바8부터 스트림이 도입된게 엄청난 변경점이라고 하던데 그 이유가 있던 것 같다.
'이론 정리 > java' 카테고리의 다른 글
java stream collector (1) | 2023.12.30 |
---|---|
스트림 활용법 (1) | 2023.11.04 |
java의 HashMap과 해시 충돌(collision) 관련 (0) | 2023.08.23 |
람다 표현식 (0) | 2023.08.05 |
동적 파라미터화 (0) | 2023.07.12 |