JAVA - Stream이란?
Stream이란?
Stream은 원문 그대로 해석시 “흐르다” 라는 뜻을 가지고 있습니다. 기술의 개발로 인해 서비스가 고도화되고 복잡해지면서 데이터 처리에 대해 효율적인 방안이 필요했고, 그러다 나온 것이 이 Stream입니다.
Stream은 Oracle 공식문서에서 “연속된 데이터를 효율적으로 처리하기 위한 인터페이스” 라고 나와있습니다.이제부터 그 이유를 알아보겠습니다.
우선 코드로 어떤 점이 차이가 나는지 알아보겠습니다.
우선 컬렉션을 하나 만들어 두겠습니다.
다음 값을 출력하면 해당 리스트가 생겼습니다.
여기서 저는 “구” 라는 성을 가진 데이터만 뽑아서 리스트를 가져오고 싶다는 요청을 받았다고 가정하고, 우선 1번째 글자가 구씨인 데이터만 골라서 다른 리스트를 가지도록 해보겠습니다.
public class Main {
public static void main(String[] args) {
List<String> humenName = new ArrayList<>();
humenName.add("구길동");
humenName.add("홍길동");
humenName.add("김길동");
System.out.println(humenName);
List<String> kooList = new ArrayList<>();
for (int i = 0; i < humenName.size(); i++) {
String name = humenName.get(i);
String nameSlice = name.substring(0,1);
if (nameSlice.equals("구")) {
kooList.add(name);
}
}
System.out.println(kooList);
}
}
이렇게 간단한 주제임에도 반복문이 5줄이나 나오며, 쓸모없이 하나의 변수가 더 나오게 되어버렸습니다.
그렇다면 이것을 스트림과 람다식 문법으로 사용하면 어떻게 변할까요?
List<String> kooList = humenName.stream()
.filter(item -> item.substring(0,1).equals("구"))
.collect(Collectors.toList());
보시면 머 쓸데없는 코드를 제외하더라도 코드의 순수한 양은 물론이고, 가독성도 좋아진 것을 한눈에 보실 수 있습니다.
이렇게 코드를 먼저 비교해봤는데요, 코드의 관리나 개발측면에서도 스트림을 사용하면 좋을 거같아 현재 신규 프로젝트에도 사용해보고 있습니다.
Stream의 특징
이제 코드로 사용해야하는 간단한 이유를 먼저 알아봤으니 Stream의 특징과 그에 따라오는 장점을 알아볼 차례입니다.
- 파이프 라이닝
- 위의 코드를 보시면 데이터를 스트림화 하고 필터링 후에 콜렉션화 하는 과정이 이어져 있으며, 그에 따라 자연스럽게 파이프라인이 잡혀있는 것을 볼 수 있습니다.
- 이렇게 스트림 연산은 연산끼리 연결해서 스트림 자신을 반환하는데, 여기에서 laziness(게으름)과 short-circuting(쇼트서킷)이라는 장점을 얻을 수 있습니다.
- laziness(지연) : Stream은 코드가 읽히는 즉시 연산을 하지 않고 최소한의 준비작업만 실시하다가, 해당 결과값에 대한 호출이 있을 때 계산한다.
- loop Fusion(반복병합) : 연속적으로 체이닝된 복수의 연산을 하나로 병합시킨다.
- short-circuting(쇼트 서킷) : 불필요하다 판단된 연산의 수행을 하지않고 중단한다.
- 내부 반복
- Stream은 Collection과 반복문을 명시하지않아도 내부에서 순환시킬 수 있다.
이렇게 여러가지 장점에 대해 찾아보았습니다. 물론 Stream이 만능은 아닐 것입니다.
기본적으로 호출 시점이 확실하고 용량이 큰 BLOB데이터 같은 경우에는 비동기로 돌려서 미리 호출에 대비해야하지않나 라는 아주 얕은 생각이 내비치기도 하였으며,
파이프라인을 DB에 쿼리문 튜닝으로 1차적으로 잡아야 좀 더 효율적으로 움직일 수 있을거라는 생각도 조금은 들었습니다.
다음번에 Stream의 여러 종류중 하나에 대해 다루게 된다면 이 이론들을 다시 곱씹어 보겠습니다.
Stream이란?
Stream은 원문 그대로 해석시 “흐르다” 라는 뜻을 가지고 있습니다. 기술의 개발로 인해 서비스가 고도화되고 복잡해지면서 데이터 처리에 대해 효율적인 방안이 필요했고, 그러다 나온 것이 이 Stream입니다.
Stream은 Oracle 공식문서에서 “연속된 데이터를 효율적으로 처리하기 위한 인터페이스” 라고 나와있습니다.이제부터 그 이유를 알아보겠습니다.
우선 코드로 어떤 점이 차이가 나는지 알아보겠습니다.
우선 컬렉션을 하나 만들어 두겠습니다.
다음 값을 출력하면 해당 리스트가 생겼습니다.
여기서 저는 “구” 라는 성을 가진 데이터만 뽑아서 리스트를 가져오고 싶다는 요청을 받았다고 가정하고, 우선 1번째 글자가 구씨인 데이터만 골라서 다른 리스트를 가지도록 해보겠습니다.
public class Main {
public static void main(String[] args) {
List<String> humenName = new ArrayList<>();
humenName.add("구길동");
humenName.add("홍길동");
humenName.add("김길동");
System.out.println(humenName);
List<String> kooList = new ArrayList<>();
for (int i = 0; i < humenName.size(); i++) {
String name = humenName.get(i);
String nameSlice = name.substring(0,1);
if (nameSlice.equals("구")) {
kooList.add(name);
}
}
System.out.println(kooList);
}
}
이렇게 간단한 주제임에도 반복문이 5줄이나 나오며, 쓸모없이 하나의 변수가 더 나오게 되어버렸습니다.
그렇다면 이것을 스트림과 람다식 문법으로 사용하면 어떻게 변할까요?
List<String> kooList = humenName.stream()
.filter(item -> item.substring(0,1).equals("구"))
.collect(Collectors.toList());
보시면 머 쓸데없는 코드를 제외하더라도 코드의 순수한 양은 물론이고, 가독성도 좋아진 것을 한눈에 보실 수 있습니다.
이렇게 코드를 먼저 비교해봤는데요, 코드의 관리나 개발측면에서도 스트림을 사용하면 좋을 거같아 현재 신규 프로젝트에도 사용해보고 있습니다.
Stream의 특징
이제 코드로 사용해야하는 간단한 이유를 먼저 알아봤으니 Stream의 특징과 그에 따라오는 장점을 알아볼 차례입니다.
- 파이프 라이닝
- 위의 코드를 보시면 데이터를 스트림화 하고 필터링 후에 콜렉션화 하는 과정이 이어져 있으며, 그에 따라 자연스럽게 파이프라인이 잡혀있는 것을 볼 수 있습니다.
- 이렇게 스트림 연산은 연산끼리 연결해서 스트림 자신을 반환하는데, 여기에서 laziness(게으름)과 short-circuting(쇼트서킷)이라는 장점을 얻을 수 있습니다.
- laziness(지연) : Stream은 코드가 읽히는 즉시 연산을 하지 않고 최소한의 준비작업만 실시하다가, 해당 결과값에 대한 호출이 있을 때 계산한다.
- loop Fusion(반복병합) : 연속적으로 체이닝된 복수의 연산을 하나로 병합시킨다.
- short-circuting(쇼트 서킷) : 불필요하다 판단된 연산의 수행을 하지않고 중단한다.
- 내부 반복
- Stream은 Collection과 반복문을 명시하지않아도 내부에서 순환시킬 수 있다.
이렇게 여러가지 장점에 대해 찾아보았습니다. 물론 Stream이 만능은 아닐 것입니다.
기본적으로 호출 시점이 확실하고 용량이 큰 BLOB데이터 같은 경우에는 비동기로 돌려서 미리 호출에 대비해야하지않나 라는 아주 얕은 생각이 내비치기도 하였으며,
파이프라인을 DB에 쿼리문 튜닝으로 1차적으로 잡아야 좀 더 효율적으로 움직일 수 있을거라는 생각도 조금은 들었습니다.
다음번에 Stream의 여러 종류중 하나에 대해 다루게 된다면 이 이론들을 다시 곱씹어 보겠습니다.