기존에 우리가 알고 있던 스트림은 실제의 입력이나 출력이 표현된 데이터의 이상화된 흐름 , 운영체제에 의해 생성되는 가상의 연결 고리를 의미하며, 중간 매개자 역할을 하는 것이었다.
JAVA 8에서부터 Stream이라는 개념이 도입되었는데, 이는 기존에 알고 있던 Stream과는 다른 의미이고, 다른 역할을 한다.
이는 람다를 활용할 수 있는 기술 중 하나인데, 자바8 이전에는 배열 또는 컬렉션 인스턴스를 다루는 방법은 for 또는 foreach문을 돌면서 요소 하나씩을 꺼내서 다루는 방법이었다. 간단한 경우라면 상관없지만 로직이 복잡해질 수록(타입이 클래스이자 참조 연관관계가 깊으며 인스턴스가 많은 경우) 코드 양이 매우 많아져 여러 로직이 섞이게 되고, 메소드를 나눌 경우 루프를 여러 번 도는 경우가 발생한다.
스트림은 '데이터의 흐름'이다. 배열 또는 컬렉션 인스턴스에 함수 여러 개를 조합해서 원하는 결과를 필터링하고 가공된 결과를 얻을 수 있다. 또한 람다를 이용해서 코드의 양을 줄이고 간결하게 표현할 수 있다. 즉, 배열과 컬렉션을 함수형으로 처리할 수 있다.
또 하나의 장점은 간단하게 병렬처리(multi-threading)이 가능하다는 점이다. 하나의 작업을 둘 이상의 작업으로 잘게 나누어서 동시에 진행하는 것을 병렬 처리(parallel processing)라고 한다. 즉 쓰레드를 이용해 많은 요소들을 빠르게 처리할 수 있다.
스트림의 특징
스트림의 특징을 정리하면 아래와 같다.
1. 람다식으로 요소 처리 코드를 제공한다.
스트림은 람다식 또는 메소드 참조를 이용한다. 따라서 코드가 간결해 지는 장점이 있다.
스트림이 제공하는 요소 처리 메소드는 함수적 인터페이스 매개 타입을 가지기 때문에 람다식 또는 메소드 참조를 이용해서 요소 처리 내용을 매개값으로 전달할 수 있다.
2. 내부 반복자를 사용하므로 병렬 처리가 쉽다.
외부 반복자란 개발자가 코드로 직접 컬렉션의 요소를 반복해서 가져오는 코드 패턴을 말한다. 우리가 흔히 사용하는 index를 이용한 반복문이나 Iterator를 사용한 while문은 모두 외부 반복자를 이용하는 것이다. 반면, 내부 반복자는 컬렉션 내부에서 요소들을 반복시키고, 개발자는 요소당 처리해야 할 코드만 제공하는 코드 패턴을 말한다.
내부 반복자는 요소들의 변경 순서를 변경하거나 멀티 코어 CPU를 최대한 활용하기 위해서 요소들을 분배시켜 병렬 작업을 할 수 있도록 도와준다.
스트림은 람다식으로 요소 처리 내용만 전달할 뿐, 반복은 컬렉션 내부에서 일어난다. 따라서, 요소의 병렬처리가 컬렉션 내부에서 처리되므로 효율적인 병렬 처리가 가능하다.
아래는 직렬처리와 병렬처리의 예시이다.
List<String> list = Arrays.asList("가", "나", "다", "라", "마", "바", "사");
//직렬 처리
//list.stream().forEach(Main::print);
list.forEach(Main::print);
System.out.println();
//병렬 처리
list.parallelStream().forEach(Main::print);
3. 중간 처리와 최종 처리가 존재한다.
스트림은 컬렉션의 요소에 대해 중간 처리와 최종 처리를 수행할 수 있는데, 중간 처리에서는 매핑, 필터링, 정렬을 사용하고, 최종 처리에서는 반복, 카운팅, 평균, 총합 등의 집계 처리를 수행한다.
아래는 등차수열의 합을 구하는 코드이다.
class Solution {
public int solution(int a, int d, boolean[] included) {
return IntStream
.range(0,included.length)
.map(i->included[i]?a+i*d:0)//중간처리(삼항연산자로 매핑)
.sum();//최종처리(총합)
}
}
'DEV > JAVA' 카테고리의 다른 글
자바의 차트 라이브러리 - JFreeChart (1) | 2023.10.12 |
---|---|
Java8부터 도입된 Stream(2) - Stream 중간처리 메소드 (0) | 2023.08.11 |
인터페이스 정리 코드(자바) (0) | 2022.11.18 |
추상 클래스와 인터페이스의 차이 (0) | 2022.11.18 |