상세 컨텐츠

본문 제목

[JAVA] 스트림(Stream)이란 - (1)

Spring/JAVA

by Chan.94 2024. 1. 20. 16:28

본문

반응형

스트림(Stream)이란

스트림(Stream)은 자바 8 API에 새로 추가된 기능이다. 스트림을 이용하면 선언형(더 간결하고 가독성이 좋도록)으로 컬렉션 데이터를 처리할 수 있다.

 

스트림은 파이프라이닝내부반복이라는 특징을 가지고 있으며 스트림의 연산은 중간연산, 최종연산으로 구분된다.

 

중간연산은 layziess(게으름), loop fusion(루프 퓨전)의 특징을 가진다.

최종연산을 하게되면 해당 스트림은 재사용을 할 수 없다는 특징을 가진다.

 

스트림 연산

중간 연산

필터링(filtering) 및 맵핑(mapping) 등 요소의 범위를 줄여나가는 연산이다.

중간 연산 메소드들은 중간 처리된 '스트림'을 리턴한다. 그리고 이 스트림에서 다시 중간 처리 메서드를 호출해서 파이프라인을 형성하게 된다. 이렇게 생성된 파이프라인은 layziess(게으름), 루프 퓨전(loop fusion)이라는 중요한 특징을 가지고 있다.

 

layziess(게으름) : 최종연산이 실행되기 전까지 중간연산(filter, sorted, map 등)이 수행하지 않는다는 것이다.

loop fusion(루프퓨전) : 중간 연산 (filter, map, 등)이 서로 다른 연산이지만 한 과정으로 병합되어 수행된다.

 

 


최종 연산

스트림 파이프라인에서 결과를 도출한다.

최종 연산을 하게 되면 해당 스트림은 닫치게 되고 재사용할 수없다.

 

내부반복

컬렉션과의 차이를 생각하면 내부반복이 어떤 것인지 이해하기 쉽다.
컬렉션을 사용하려면 사용자가 직접 요소를 반복(ex: for-each문) 해야 하는데 이를 외부반복이라 한다.

반면 스트림은 반복을 알아서 처리하고 결과 스트림 값을 어딘가에 저장해 주는 내부반복을 사용한다.


Example - layziess & loop fusion

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamLayzCalc {

	public static void main(String[] args) {
		List<People> peopleList = new ArrayList<People>();
		peopleList.add(new People(20, 180, "Kim"));
		peopleList.add(new People(17, 183, "Kang"));
		peopleList.add(new People(25, 175, "Park"));
		peopleList.add(new People(18, 177, "Zo"));
		peopleList.add(new People(22, 171, "Lee"));
		
		int nFilterAge = 20;
		int nFilterHeight = 175;
		Stream<String> filterStream = peopleList.stream()
						.filter(data -> {
							System.out.println(String.format("filter : %s, %d, %d", data.name, data.age, data.height));
							return (data.getAge() >= nFilterAge && data.getHeight() >= nFilterHeight);
						})
						.map(data -> {
							System.out.println(String.format("map : %s, %d, %d", data.name, data.age, data.height));
							return data.getName();
						});
						.collect(Collectors.toList());
		
		System.out.println("=========Print Start=========");
		List<String> filterList = filterStream.collect(Collectors.toList());
		System.out.println("=========Print End=========");
		System.out.println("filterList : " + filterList.toString());
        
		//System.out.println("firstFilter : " + filterStream.findFirst());	// IllegalStateException
	}

	static class People{
		int age;
		int height;
		String name;
		
		private People(int age, int height, String name) {
			this.age = age;
			this.height = height;
			this.name = name;
		}
		private int getAge() {
			return age;
		}
		private void setAge(int age) {
			this.age = age;
		}
		private int getHeight() {
			return height;
		}
		private void setHeight(int height) {
			this.height = height;
		}
		private String getName() {
			return name;
		}
		private void setName(String name) {
			this.name = name;
		}
	}
}

 

Output

=========Print Start=========
filter : Kim, 20, 180
map : Kim, 20, 180
filter : Kang, 17, 183
filter : Park, 25, 175
map : Park, 25, 175
filter : Zo, 18, 177
filter : Lee, 22, 171
=========Print End=========
filterList : [Kim, Park]

 

출력순서를 통해 layziess(게으름)의 특징을 확인할 수 있다.

filter 된 것만 map에서 출력된 것을 통해 loop fusion(루프퓨전)의 특징을 확인할 수 있다.

스트림을 재사용할시 IllegalStateException 예외 발생을 통해 재사용 할 수 없는 특징을 확인할 수 있다.

 


반응형

관련글 더보기

댓글 영역

>