Java

Stream API

파란배개 2025. 1. 25. 17:59

함수형 프로그래밍과 스트림

  • 함수형 프로그래밍: 상태 변경을 피하고 사이드 이펙트를 최소화하여 안정성과 예측 가능성을 향상시키는 프로그래밍 패러다임.
  • 스트림: 함수형 프로그래밍 개념을 자바에 도입하여 컬렉션을 선언적으로 처리할 수 있는 기능.

함수형 프로그래밍의 핵심 개념

  1. 불변성:
    • 데이터가 생성된 후 변경되지 않음.
    • 데이터를 변경하려면 새로운 객체를 생성해야 함.
  2. 순수 함수:
    • 동일한 입력에 대해 언제나 동일한 결과를 반환.
    • 사이드 이펙트 없음.
  3. 일급 함수:
    • 함수를 반환하거나 할당 가능.
    • 함수를 인자로 전달 가능.
  4. 고차 함수:
    • 다른 함수를 반환하거나 인자로 받을 수 있음.
    • 추상화 수준과 재사용성을 높임.
  5. 조합 함수:
    • 작은 함수를 조합하여 더 큰 함수 생성 가능.

자바 스트림의 특징

  1. 선언형 프로그래밍:
    • "어떻게"(명령형)보다 "무엇을"(선언형)에 집중.
  2. 사이드 이펙트 최소화:
    • 동일한 입력에 대해 외부 상태를 변경하지 않고 동일한 결과를 반환.
  3. 병렬 처리 용이:
    • 외부 상태를 변경하지 않으므로 데이터 간섭 없이 병렬 처리 가능.
    • parallel() 메서드를 통해 병렬 처리 지원.
    • 예시: 데이터 크기가 클수록 병렬 처리가 유리 (ex. 1억 단위 데이터).

스트림의 사용 시점

사용하기 좋은 경우:

  1. 병렬 처리가 유리한 상황:
    • 대량 데이터 처리.
    • CPU 연산이 많은 경우.
    • 다른 작업 결과에 의존하지 않는 작업.
    • 적절한 데이터 구조와 작업 크기가 있을 때.
  2. 데이터 컬렉션에 대한 연속된 필터링, 변환, 집계가 필요한 경우:
    • 예: 대규모 데이터 변환, 필터링 후 요약 통계 계산 등.

사용하면 안 되는 경우:

  1. 스트림 오버헤드가 발생하는 상황:
    • 데이터 크기가 작을 때.
    • 박싱과 언박싱이 잦은 경우.
    • 불필요한 연산(filter, sorted 등)을 여러 번 사용하는 경우.
    • 중간 연산이 복잡하거나 연산 비용이 높은 경우.
  2. 성능이 중요한 반복 작업:
    • 명령형 for-loop보다 성능이 떨어질 수 있음.
    • 추가적인 추상화 계층, 박싱/언박싱 비용, 중간 연산 비용이 발생.

참고 - 박싱(Boxing)과 언박싱(Unboxing)

  1. 박싱(Boxing):
    • 기본 자료형(int, double 등)을 해당하는 래퍼 클래스(Integer, Double 등) 객체로 변환하는 과정.
    • 예: int a = 10; Integer b = Integer.valueOf(a);
  2. 언박싱(Unboxing):
    • 래퍼 클래스 객체를 기본 자료형으로 변환하는 과정.
    • 예: Integer a = 10; int b = a.intValue();
  3. 자동 박싱과 언박싱:
    • Java 5부터는 컴파일러가 자동으로 박싱과 언박싱을 처리.
    • 예:
    • Integer a = 10; // 자동 박싱 int b = a; // 자동 언박싱
  4. 문제점:
    • 박싱과 언박싱 과정은 추가적인 연산 비용을 발생시키므로 반복적으로 사용되면 성능 저하 가능.

주의 사항

  • 스트림의 사용 여부는 상황에 따라 판단해야 함.
  • 스트림의 이점(간결성, 병렬 처리)과 오버헤드(추가 연산 비용)를 고려해 적합한 경우에 사용.

'Java' 카테고리의 다른 글

제네릭의 정의와 설명  (1) 2025.01.05
ArrayList와 List  (1) 2025.01.03