스트림이란 무엇일까요?
Java에서 컬렉션을 알고 있죠? List같은거요. 컬렉션은 Java에서 많이 사용하는 기능 입니다. 거의 모든 어플리케이션은 컬렉션을 만들고 데이터를 넣고 그룹화하고 데이터를 처리 합니다.
하지만 보통은 데이터를 담고 전달하는 수준에서만 사용하죠. 예를 들면 게시판에서 가장 많은 댓글을 게시물을 찾는 기능이 있다고 합시다. 실제로 컬렉션을 이용해서 이 기능을 구현해 본사람은 거의 없을 껍니다. 왜냐하면 보통 DB에서 쿼리로 구현해서 댓글이 많은 데이터를 가져왔을 꺼니까요. 만약에 컬렉션을 통해서 이런 기능을 구현하려면 어떻게 해야 할까요? 만약 수천, 수억건의 데이터를 처리해야한다면 어떻게 해야할까요?
스트림이란?
스트림은 컬렉션 데이터를 처리 하며, 별다른 설정없이 병렬 처리 할 수 있도록 도와줍니다. 아래는 스트림의 사용예 입니다.List threeYearsUnitFirstNameList = unitList.stream()
.filter((unit) -> unit.getAge() > 30)
.sorted(comparing((u) -> u.getAge()))
.map((unit) -> unit.getFirstName())
.collect(Collectors.toList());
만약 stream()을 parallelStream으로 변경하면 단일 스레드가 아닌 병렬로 데이터를 처리합니다. parallelStream의 구조와 성능에 관해서는 차후 설명을 하겠습니다.
아직 스트림이라는게 뜬 구름 같은 소리라고 생각이 드실꺼라고 봅니다. 스트림의 특징을 한번 보시면서 이런거구나 하고 우선 아시면 좋을꺼 같습니다. 그리고 다음장에서 여러 스트림의 활용 방법에 대해서 정리를 하도록 하겠습니다.
특징
연속된 데이터 처리스트림은 연속적인 데이터 집합의 처리 도구라고 볼수 있는데 스트림은 이런 데이터 집합을 처리하는 계산식을 메인으로 봅니다. 예를 들자면 map, filter, sort등이라고 할 수 있습니다.
소스
스트림은 컬렉션, 배열, I/O리소스 등등에서 데이터를 사용할 수 있습니다.
데이터 처리 연산
스트림은 함수형 프로그래밍 언어에서 지원하는 연산등을 지원해줍니다. 예를 들면 filter, map, reduce, find, match, sort등으로 데이터를 조작 할 수 있습니다. 또한 순차적으로나 병렬적으로 데이터를 처리 할 수 있습니다.
파이프라이닝
스트림의 연산은 스트림 연산끼리 연결해서 커다란 파이프라인을 구성할 수 있도록 스트림을 반환한다. 덕분에 Lazy나 short-circuting을 사용할 수 있다. 자세한건 차후에 정리를 하도록 하겠다.
내부반복
컬렉션 같은 경우 컬렉션을 처리 하기 위해선 사용자가 직접 for문이나 while문을 사용해서
직접 요소하나하나씩 직접 처리를 해주어야 합니다. 이것을 외부 반복이라 이야기 합니다. 그에 비해 스트림은 별도 반복문 없이 어떤 작업을 할지 정의하면 알아서 반복적으로 처리합니다. 이것을 내부 반복이라 합니다.
소비
스트림은 처리시 데이터를 소비를 하기 때문에 이전에 처리한 데이터를 다시 반복해서 사용 할 수 없습니다. 만약 사용하려면 이전 데이터를 다시 스트림으로 변환해서 사용해야 합니다.
스트림 연산
스트림은 크게 2가지의 연산으로 구분을 할 수 있는데, 중간연산과 최종연산이라고 부릅니다. 위에서 파이프라이닝 절을 보면 스트림은 연산끼리 연결해서 파이프라인을 구성하고 처리는 Lazy한다고 했었습니다. 즉 중간 연산을 하나하나씩 처리하는게 아닌 한묶음으로 묶어서 처리하고 마지막에 최종연산을 처리하는 형태입니다.요약
스트림은 요약하자면 다음과 같습니다.- 질의를 수행할 데이터 소스
- 스트림 파이프라인을 구성할 중간 연산 연결
- 스트림 파이프라인을 실행하고 결과를 만들어낼 최종연산
COMMENTS