함수형 프로그래밍과 스트림
- 함수형 프로그래밍: 상태 변경을 피하고 사이드 이펙트를 최소화하여 안정성과 예측 가능성을 향상시키는 프로그래밍 패러다임.
- 스트림: 함수형 프로그래밍 개념을 자바에 도입하여 컬렉션을 선언적으로 처리할 수 있는 기능.
함수형 프로그래밍의 핵심 개념
- 불변성:
- 데이터가 생성된 후 변경되지 않음.
- 데이터를 변경하려면 새로운 객체를 생성해야 함.
- 순수 함수:
- 동일한 입력에 대해 언제나 동일한 결과를 반환.
- 사이드 이펙트 없음.
- 일급 함수:
- 함수를 반환하거나 할당 가능.
- 함수를 인자로 전달 가능.
- 고차 함수:
- 다른 함수를 반환하거나 인자로 받을 수 있음.
- 추상화 수준과 재사용성을 높임.
- 조합 함수:
- 작은 함수를 조합하여 더 큰 함수 생성 가능.
자바 스트림의 특징
- 선언형 프로그래밍:
- "어떻게"(명령형)보다 "무엇을"(선언형)에 집중.
- 사이드 이펙트 최소화:
- 동일한 입력에 대해 외부 상태를 변경하지 않고 동일한 결과를 반환.
- 병렬 처리 용이:
- 외부 상태를 변경하지 않으므로 데이터 간섭 없이 병렬 처리 가능.
- parallel() 메서드를 통해 병렬 처리 지원.
- 예시: 데이터 크기가 클수록 병렬 처리가 유리 (ex. 1억 단위 데이터).
스트림의 사용 시점
사용하기 좋은 경우:
- 병렬 처리가 유리한 상황:
- 대량 데이터 처리.
- CPU 연산이 많은 경우.
- 다른 작업 결과에 의존하지 않는 작업.
- 적절한 데이터 구조와 작업 크기가 있을 때.
- 데이터 컬렉션에 대한 연속된 필터링, 변환, 집계가 필요한 경우:
- 예: 대규모 데이터 변환, 필터링 후 요약 통계 계산 등.
사용하면 안 되는 경우:
- 스트림 오버헤드가 발생하는 상황:
- 데이터 크기가 작을 때.
- 박싱과 언박싱이 잦은 경우.
- 불필요한 연산(filter, sorted 등)을 여러 번 사용하는 경우.
- 중간 연산이 복잡하거나 연산 비용이 높은 경우.
- 성능이 중요한 반복 작업:
- 명령형 for-loop보다 성능이 떨어질 수 있음.
- 추가적인 추상화 계층, 박싱/언박싱 비용, 중간 연산 비용이 발생.
참고 - 박싱(Boxing)과 언박싱(Unboxing)
- 박싱(Boxing):
- 기본 자료형(int, double 등)을 해당하는 래퍼 클래스(Integer, Double 등) 객체로 변환하는 과정.
- 예: int a = 10; Integer b = Integer.valueOf(a);
- 언박싱(Unboxing):
- 래퍼 클래스 객체를 기본 자료형으로 변환하는 과정.
- 예: Integer a = 10; int b = a.intValue();
- 자동 박싱과 언박싱:
- Java 5부터는 컴파일러가 자동으로 박싱과 언박싱을 처리.
- 예:
- Integer a = 10; // 자동 박싱 int b = a; // 자동 언박싱
- 문제점:
- 박싱과 언박싱 과정은 추가적인 연산 비용을 발생시키므로 반복적으로 사용되면 성능 저하 가능.
주의 사항
- 스트림의 사용 여부는 상황에 따라 판단해야 함.
- 스트림의 이점(간결성, 병렬 처리)과 오버헤드(추가 연산 비용)를 고려해 적합한 경우에 사용.
'Java' 카테고리의 다른 글
제네릭의 정의와 설명 (1) | 2025.01.05 |
---|---|
ArrayList와 List (1) | 2025.01.03 |