스트림(Stream)이란?

신민철·2023년 3월 31일
1
post-thumbnail

스트림이란?

“Stream”이라는 단어의 사전적 의미는 “흐르다”라는 의미를 가지고 있다. Java에서도 비슷한 의미인데 여기에서는 “데이터”의 흐름을 말한다.

그림에서 보는 것처럼 물고기들을 그물로 잡고 일정 기준으로 박스에 담아서 하나로 모은 뒤 트럭으로 실어 보낸다.

  1. 어부가 어류 중에서도 고등어를 잡고 싶어서 그물로 고등어를 잡았는데 이 행위를 filter라고 하고 이 연산자를 중간 연산자라고 한다.
  2. 고등어를 상자에 담아서 운송해야 한다. 이 행위를 map이라고 하고 이 연산자도 마찬가지로 중간 연산자라고 한다.
  3. 마지막으로, 고등어가 실린 박스를 운송해야 하는데 이 행위를 collect라고 하고 이 연산자는 최종 연산자라고 한다.

Stream의 특징

  1. Stream은 데이터를 담는 저장소가 아니다.
  2. Stream은 데이터를 변경하지 않는다.
  3. Stream은 재사용할 수 없다.
  4. Stream은 각 요소가 1번씩 처리된다.
  5. Stream은 무제한일 수도 있다. (실시간적으로)

Stream 사용법 : 데이터.Stream생성().중개연산()…종료연산();

중개 연산

  • 계속 연산을 추가할 수 있다.
  • Stream을 리턴한다.
  • Lazy하다. (종료 연산이 오기 전에는 실행하지 않음)
  • Stateless / Stateful 오퍼레이션으로 구분할 수 있다. → sorted의 경우 Stateful이라고 한다. 이전 데이터를 참고하기 때문.
  • 종류 : filter, map, limit, skip, sorted …

종료 연산

  • 더 이상 연산을 연결할 수 없다.
  • Stream을 리턴하지 않는다.
  • 종류 : collect, allMatch, count, forEach, min, max

예제

names.stream().skip(3).map((n) -> {
	System.out.println(n);
	return "success";
});

해당 코드는 skip, map이라는 중개 연산자 혹은 중간 연산자만 존재하므로 어떤 결과도 출력하지 않는다.

List<Integer> names = Arrays.asList(1, 2, 3, 4);

names.stream().skip(3).map((n) -> {
    System.out.println(n);
    return "success";
}).forEach(System.out::println);

이제 결과가 출력되는데 종료 연산자인 forEach가 붙었기 때문이다.

줄 수를 줄이는 Stream 코드

public class Main {

public static void main(String[] args) {
	List<Integer> list = Arrays.asList(1, 2, 3);
		Iterator<Integer> it = list.iterator();
		while (it.hasNext()) {
		  int num = it.next();
		  System.out.println(num);
		}
	}
}
	public class Main {
	
	public static void main(String[] args) {
	  List<Integer> list = Arrays.asList(1, 2, 3);
	  Stream<Integer> stream = list.stream();
	  stream.forEach(System.out::println);
	}

}

여기서 또 파악할 수 있는 특징

  1. 람다식으로 요소 처리 코드를 제공한다.
    1. 위에서 볼 수 있듯이, Stream은 람다식 혹은 메소드 참조를 이용한다. 따라서 코드가 간결해진다.
  2. 내부 반복자를 사용하므로 병렬 처리가 쉽다.

→ 외부 반복자란 개발자가 코드를 직접 컬렉션의 요소를 반복해서 가져오는 패턴을 의미한다. 우리가 흔히 사용하는 index나 Iterator를 사용한 while문은 모두 외부 반복자를 사용하는 것이다. 반면에 내부 반복자는 컬렉션 내부에서 요소들을 반복시킨다. 개발자는 요소당 처리해야 할 코드만 제공한다.

→ 내부 반복자는 요소들의 변경 순서를 변경하거나, 멀티 코어 CPU를 최대한 활용하기 위해서 요소들을 분배시켜 병렬 작업을 할 수 있도록 도와준다.

참고

Java 8 - Stream이란? (+ ParallelStream)

Stream이란? - 기본 개념과 특징 (JAVA)

0개의 댓글