ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java - 스트림(Stream)의 기본 개념과 특징
    Language/Java 2022. 11. 30. 15:01

    스트림(Stream)의 기본 개념과 특징

    스트림이란?

    스트림의 사적적 의미는 "흐르다." 또는 "개울"이다. 프로그래밍에서의 스트림도 사전적 의미와 크게 다르지 않다. 다만, 여기서는 물이 흐르는 것이 아닌 "데이터의 흐름"을 말한다.

     

     

    위 그림은 어부가 물고기를 그물로 잡고, 여러 마리를 일정한 기준으로 모아서 상자에 넣고, 이들을 하나로 모은 뒤 트럭에 실어서 운반하는 과정을 나타내고 있다.

    스트림도 이와 별반 다르지 않다. 물고기와 같은 어류의 이동을 스트림이라고 정의할 수 있다.

    먼저, 어부가 어류 중에서도 고등어를 잡고 싶어서 그물로 고등어를 잡았다고 가정해 보겠다. 이러한 행위를 filter라고 하고, 이 연산자를 중간 연산자라고 한다.

    그리고 고등어를 포장하지 않고 생으로 팔 수는 없기 때문에 상자에 담아야 한다. 이러한 행위를 map이라고 하고, 이 연산자도 마찬가지로 중간 연산자라고 한다.

    마지막으로, 고등어가 실린 수많은 상자를 운반하여 다른 곳으로 이동하면 끝이 난다. 이 행위를 collect라고 하고, 이 연산자는 최종 연산자라고 한다.

    이렇게, 스트림은 수많은 데이터의 흐름 속에서 각각의 원하는 값을 가공하여 최종 소비자에게 제공하는 역할을 한다.

     

    스트림의 특징

    기능적인 측면에서 스트림은 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있는 반복자이다. 우리는 사실 반복자를 스트림이 아니더라고 계속 사용해 왔다. 단적인 예로 Iterator 반복자가 있다.

     

    public class Main {
        public static void main(String[] args) {
            List<Integer> list = Arrays.asList(1, 2, 3);
            Iterator<Integer> iterator = list.iterator();
            while (iterator.hasNext()) {
                int num = iterator.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(x -> System.out.println(x));
        }
    }

    위에서 작성한 소스 코드를 스트림으로 바꿔보았다. 기존의 소스 코드보다 간결해진 것을 확인할 수 있다.

     

    이제, 스트림의 특징이 무엇인지 알아보겠다.

     

    1. 람다식을 통해 요소 처리 코드를 제공

    위에서 알 수 있었듯이, 스트림은 람다식 또는 메서드 참조를 이용한다. 따라서, 코드가 더 간결해진다는 장점이 있다.

     

    2. 내부 반복자를 사용하므로 병렬 처리에 용이

    외부 반복자란 개발자가 코드로 직접 컬렉션의 요소를 반복해서 가져오는 것을 의미한다. 우리가 흔히 사용하는 index를 이용한 반복문이나 Iterator를 사용한 while문 모두 외부 반복자를 이용한 것이다.

    반면, 내부 반복자는 컬렉션 내부에서 요소들을 반복시키고, 개발자는 요소당 처리해야 할 코드만 제공하는 코드 패턴을 말한다.

     

     

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

    스트림은 람다식으로 요소 처리 내용만 전달할 뿐, 반복은 컬렉션 내부에서 일어난다. 따라서, 요소의 병렬 처리가 컬렉션 내부에서 처리되므로 효율적인 병렬 처리가 가능하다.

     

    3. 중간 처리와 최종 처리가 존재

    스트림은 컬렉션의 요소에 대해 중간 처리와 최종 처리를 수행할 수 있다.

    중간 처리에서는 매핑, 필터링, 정렬을 수행하고 최종 처리에서는 반복, 카운팅, 평균, 총합 등의 집계 처리를 수행한다.

    예를 들어, 학생 객체를 요소로 가지는 컬렉션이 있다고 가정하면, 중간 처리에서 학생의 수학 점수를 뽑아내고 최종 처리에서는 수학 점수의 평균값을 계산하는 행위를 할 수 있다.


    출처

    https://steady-coding.tistory.com/309

     

    728x90

    댓글

Designed by Tistory.