정말 아무것도 모르고 스트림을 사용할 때가 있었다. 람다조차 모를때 코드가 간편해진다는 이유로 기존 코드를 스트림으로 변환했던 기억이 있다. 그리고 블로그 글을 봐도 잘 이해가 가지 않았다... 나와 비슷한 사람을 위해(또는 나를 위해) 간단히 정리해보자!
스트림이란?
스트림이란 '데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소'로 정의할 수 있다. 이게 도대체 무슨 말인가.... 비루한 머리로 해석해보자면 데이터 처리를 할때,,, 안되겠다 하나하나 알아보자
- 연속된 요소 : 컬렉션과 마찬가지로 스트림은 특정 요소 형식으로 이루어진 연속된 값 집합의 인터페이스를 제공한다. 컬렉션은 자료구조이므로 컬렉션에서는 시간과 공간의 복잡성과 관련된 요소 저장 및 접근 연산이 주를 이룬다. (ArrayList인가 LinkedList인가) 반면에 스트림은 filter, sorted, map처럼 표현 계산식이 주를 이룬다. 즉, 컬렉션의 주제는 데이터고 스트림의 주제는 "계산"이다
- 소스 : 스트림은 기존의 데이터를 제공해주는 컬렉션, 배열, I/O 자원 등의 데이터 제공 소스로부터 데이터를 소비한다. 정렬된 컬레션으로 스트림을 생성하면 정렬이 그대로 유지된다. 즉, 리스트로 스트림을 만들면 스트림의 요소는 리스트의 요소와 같은 순서를 유지한다.
- 데이터 처리 연산 : 스트림은 함수형 프로그래밍 언어에서 일반적으로 지원하는 연산과 데이터베이스와 비슷한 연산을 지원한다. 예를 들어 filter, map, reduce, find, match, sort 등으로 데이터를 조작할 수 있다. 스트림 연산은 순차적으로 또는 병렬로 실행할 수 있다.
자 이제 다시 올라가 문장을 해석해보자. 다양한 데이터를 조작할 수 있는 함수를 사용할 수 있도록 기존 데이터가 담겨있는 자료구조나 I/O 자원에에서 가져온 데이터를 담는 새로운 형태로 정의할 수 있다. 그냥 데이터를 다루는 새로운 연산을 다루기 위해서 기존 자료구조와 호환이 되는 새로운 자료구조로 이해하면 될것 같다.
중요 특성
스트림에는 중요한 특징이 있다.
- 파이프라이닝 : 대부분의 스트림 연산은 스트림 연산끼리 연결해서 커다란 파이프라인을 구성할 수 있도록 스트림 자산을 반환한다. 연산 파이프라인은 데이터 소스에 적용하는 데이터베이스 질의와 비슷하다.
- 내부 반복 : 반복자를 이용해서 명시적으로 반복하는 컬렉션과 달리 스트림은 내부 반복을 지원한다.
첫번째 특징은 예를 들어 list.stream().filter(조건).map(메서드참조) 이런식의 스트림 파이프라인이 있다면 steam(), filter()함수와 같은 연산은 연산 후에 스트림을 반환한다는 것이다. 그러므로 계속해서 스트림 연산을 사용할 수 있게 된다.
또 스트림은 딱 한번만 탐색할 수 있다. 만약 스트림형으로 변수를 생성하여 탐색을 한다해보자.
Stream<String> s = list.stream();
s.forEach(System.out::println);
이렇게 s의 데이터를 한번 소비했으면 s는 텅빈 변수가 된다는 의미이다. 스트림을 사용할 때 이러한 점을 잘 이해하고 유의해서 사용하도록 하자!!!!
'자바' 카테고리의 다른 글
람다를 이용하자! (0) | 2024.10.09 |
---|---|
동작 파라미터화와 람다의 관계성 (1) | 2024.09.30 |