정의

스트림이란?

데이터 처리 연산을 지원하는 추출된 연속된 요소.

자바 8 컬렉션에 stream 메서드 및 java.util.steam.Stream 에 인터페이스 정의가 추가되었다.

 

특징

1. 주제

컬렉션과 마찬가지로 스트림은 특정 요소 형식의 연속된 값 집합 인터페이스 제공.

컬렉션은 주제가 데이터이면 스트림은 데이터의 계산입니다.

 

2. 소스

스트림은 컬렉션, 배열, I/O 자원 등 데이터 제공 소스로부터 데이터를 소비.

정렬된 컬렉션으로 스트림을 생성하면 정렬이 그대로 유지.

 

3. 연산

일반적인 함수형 프로그래밍 언어 및 DB 비슷한 연산 기능 지원.

filter, map, reduce, find, match, sort 등 데이터를 조작. 

연산을 순차적, 병렬적으로 실행 가능.

 

4. 파이프라이닝

스트림 연산은 연산 끼리 연결하여 파이프 라이닝 구성 가능.

 

5. 내부 반복

외부에서 명시적으로 반복하는 컬렉션과 달리 스트림은 내부 반복 지원.

 

스트림과 컬렉션

1. 데이터 계산

컬렉션은 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 구조.

반면 스트림은 이론적으로는 요청할 때만 요소를 계산하는 구조.

 

2. 탐색

반복자와 마찬가지로 스트림도 소비되고 나면 반복 사용할 수가 없습니다.

 

3. 데이터 반복 처리

컬렉션은 요소를 사용자가 for 문 등을 사용하여 직접 요소를 꺼내어 연산하고 다시 요소를 넣는 외부 반복을 이 필요.

반면 스트림은 반복은 내부에서 알아서 처리하고 어떤 연산을 할지만 지정하면 처리가 가능.

 

스트림 연산

1. 중간 연산

filter나 sorted 같은 중간 연산은 다른 스트림을 반환.

중간 연산을 연결하여 파이프 라이닝 가능.

 

2. 최종 연산

스트림 파이프라인에서 List, Integer 등 스트림 이외의 결과를 반환.

 

비교 예제

기존 외부 반복을 통한 연산과 스트림을 통한 연산을 비교해보기 위한 간략한 예제.

1. Game 이라는 게임명, 가격을 가진 객체를 생성.

2. 30,000원 초과하는 가격의 게임의 게임명 리스트를 반환.

public class Game {
	private String name;
	private int price;
	
	public Game(String name, int price) {
		this.name = name;
		this.price = price;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
}

 

 

package demo;

import java.util.ArrayList;
import java.util.List;
import static java.util.stream.Collectors.toList;

public class Main {
	public static void main(String[] args) {
		
        // 1. 데이터 초기화
		List<Game> gameList = new ArrayList<>();
		gameList.add(new Game("Hell Gate", 39900));
		gameList.add(new Game("Heaven Gate", 49900));
		gameList.add(new Game("DIA 1", 10000));
		gameList.add(new Game("DIA 2", 20000));
		gameList.add(new Game("DIA 3", 30000));
		
        // 2. 외부반복을 통한 처리
		List<String> highPriceGameList = new ArrayList<>(gameList.size()); 
		
		for(Game game : gameList) {
			if (game.getPrice() > 30000) {
				highPriceGameList.add(game.getName());
			}
		}
		System.out.println(highPriceGameList);
	}
}

 

package demo;

import java.util.ArrayList;
import java.util.List;
import static java.util.stream.Collectors.toList;

public class Main {
	public static void main(String[] args) {
		
        // 1. 데이터 초기화
		List<Game> gameList = new ArrayList<>();
		gameList.add(new Game("Hell Gate", 39900));
		gameList.add(new Game("Heaven Gate", 49900));
		gameList.add(new Game("DIA 1", 10000));
		gameList.add(new Game("DIA 2", 20000));
		gameList.add(new Game("DIA 3", 30000));
		
        // 스트림 연산을 통한 처리
		List<String> highPriceGameList = gameList.stream()
							.filter(game -> game.getPrice() > 30000)
							.map(Game::getName)
							.limit(gameList.size())
							.collect(toList());
		System.out.println(highPriceGameList);
	}
}

 

마치며

비교적 간단한 예제라서 코드 길이는 큰 차이가 없어 보이지만 파이프 라이닝과 외부 반복 연산 없이

내부 연산을 통해 가독성이 좋게 처리가 가능하다.

 

'Java > Stream' 카테고리의 다른 글

기본형 특화 스트림  (0) 2022.10.27
리듀싱  (0) 2022.10.26
검색과 매칭  (0) 2022.10.26
map과 flatMap  (0) 2022.10.17
필터링 및 슬라이싱  (0) 2022.10.10

+ Recent posts