개발지/Today I learn

[0829] 자바 스트림

개발지의 개발자 2023. 8. 29. 21:51

#스트림

- 배열 및 컬렉션의 저장 요소를 하나씩 참조하여 람다식으로 처리할 수 있게 해주는 반복자.

 

- 선언형 프로그래밍(Declarative Programming)과 명령형 프로그래밍(Imperative Programming)

  ▪ 선언형 프로그래밍이란 코드에서 '무엇'에 집중하는 코드 작성 방법론을 말한다.

  ▪ 명령형 프로그래밍이란 코드에서 '어떻게'에 집중하는 코드 작성 방법론을 말한다.

  ▪ 선언형 프로그래밍은 내부의 동작 원리를 모르더라도 코드의 역할을 직관적으로 볼 수 있다.

 

- 스트림을 통해 선언형 프로그래밍이 가능하다.

// 명령형 프로그래밍

public class ImperativeProgramming {
    public static void main(String[] args){
        // List에 있는 숫자 중에서 5보다 큰 홀수의 합계 구하기
        List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);
        int sum = 0;

        for(int number : numbers){
            if(number > 5 && (number % 2 == 1)){
                sum += number;
            }
        }

        System.out.println("명령형 프로그래밍을 사용한 합계 : " + sum);
    }
}
// 선언형 프로그래밍
public class DeclarativePrograming {
    public static void main(String[] args){
        // List에 있는 숫자들 중에서 5보다 큰 홀수의 합계 구하기
        List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);

        int sum =
            numbers.stream()
               .filter(number -> number > 5 && (number % 2 == 1))
               .mapToInt(number -> number)
               .sum();

        System.out.println("선언형 프로그래밍을 사용한 합계 : " + sum);
    }
}

  ▪ 각 메서드에서 람다식으로 데이터를 처리할 방법을 규정할 수 있음.

 

- 스트림을 통해 데이터 소스의 유형에 상관없이 같은 방식으로 데이터를 가공/처리 할 수 있다.

import java.util.*;

public class StreamExample {
    public static void main(String[] args) {
        // ArrayList 타입
        List<String> animalList = enw ArrayList>?();
        animalList.add("호랑이");
        animalList.add("판다");
        animalList.add("토끼");
        
        // 배열 타입
        String[] animalArray = {"호랑이", "판다", "토끼"};
        
        // 스트림 생성
        Stream<String> ListStream = animalList.stream();
        Stream<String> ArrayStream = Arrays.stream(animalArray);
        
        // 출력
        ListStream.forEach(System.out::print);
        ArrayStream.forEach(System.out::print);
    }
}

//출력값
호랑이 판다 토끼 호랑이 판다 토끼

 

#스트림의 특징

(1) 스트림 처리 과정은 생성, 중간 연산, 최종 연상 총 세 단계(파이프라인)로 구성될 수 있다. 

(2) 스트림은 원본 데이터 소스를 변경하지 않는다. (읽기만 함)

(3) 스트림은 일회용이다.

(4) 스트림은 내부 반복자이다.

 

-파이프라인

  ▪ 스트림의 생성, 중간 연산, 최종 연산 순으로 이어지는 단계를 지칭.

  ▪ 3단계가 모두 있는 구성을 완전체 파이프라인이라고 한다.

  ▪ 제공된 데이터 소스를 일원화 하여 스트림으로 작업한다.

  ▪ 중간 연산을 생략 가능. 

  ▪ 최종 연산은 스트림의 요소를 소모하며 연산을 수행하기 때문에 단 한번의 연산만 가능.

 

- 내부 반복자

  ▪ 외부 반복자와 비교됨. (외부 반복자: for문, Iterator를 사용하는 while문)

  ▪ 외부 반복자는 데이터의 처리가 컬렉션 외부에서, 내부 반복자는 데이터의 처리가 컬렉션의 내부에서 일어난다.