Post
Java 스트림 API로 함수형 프로그래밍 마스터하기
Java 스트림 API로 함수형 프로그래밍 마스터하기
왜 이것이 중요한가?
실무에서 대용량 데이터를 처리할 때 스트림 API는 필수입니다. 기존의 반복문 대신 선언적이고 간결한 코드를 작성할 수 있으며, 병렬 처리도 간단하게 구현할 수 있습니다.
특히 데이터 필터링, 변환, 집계 작업에서 가독성과 성능을 동시에 확보할 수 있습니다.
핵심 개념
- 스트림의 특징 일회용이며 지연 평가(lazy evaluation)를 지원합니다
- 중간 연산 filter, map, flatMap, distinct, sorted 등으로 파이프라인을 구성합니다
- 최종 연산 collect, forEach, reduce, findFirst 등으로 결과를 도출합니다
- 함수형 인터페이스 Predicate, Function, Consumer 등을 활용한 람다식 작성
- 병렬 스트림
parallelStream()으로 멀티스레드 처리를 자동화합니다
실전 예제
Product 클래스와 데이터 준비
import java.util.*;
import java.util.stream.Collectors;
public class StreamExample {
static class Product {
String name;
int price;
String category;
Product(String name, int price, String category) {
this.name = name;
this.price = price;
this.category = category;
}
}
}
스트림 활용 예제
List<Product> products = Arrays.asList(
new Product("노트북", 1500000, "전자제품"),
new Product("마우스", 50000, "전자제품"),
new Product("책", 15000, "도서"),
new Product("키보드", 80000, "전자제품")
);
// 1. 필터링 + 매핑
List<String> expensiveItems = products.stream()
.filter(p -> p.price > 50000)
.map(p -> p.name)
.collect(Collectors.toList());
// 2. 그룹핑
Map<String, List<Product>> byCategory =
products.stream()
.collect(Collectors.groupingBy(p -> p.category));
// 3. 집계
int totalPrice = products.stream()
.mapToInt(p -> p.price)
.sum();
// 4. 조건 확인
boolean hasExpensive = products.stream()
.anyMatch(p -> p.price > 1000000);
흔한 실수
- 스트림 재사용
스트림은 일회용입니다. 한 번 최종 연산을 실행하면 다시 사용할 수 없습니다.
Stream<Integer> stream = Arrays.asList(1, 2, 3).stream(); stream.forEach(System.out::println); stream.forEach(System.out::println); // 에러! -
병렬 스트림의 무분별한 사용 작은 데이터셋에서는 오버헤드가 더 클 수 있습니다.
-
null 처리 누락 filter나 map에서 null을 반환하면
NullPointerException이 발생할 수 있습니다. - 부작용(Side Effect) 포함 스트림 내에서 외부 상태를 변경하면 병렬 처리 시 예상치 못한 결과가 나옵니다.
오늘의 실습 체크리스트
- 기본 스트림 생성 방법 3가지 이상 실습 (Arrays.stream, Collection.stream, Stream.of)
- filter와 map을 조합한 파이프라인 작성
- collect()로 List, Map, Set으로 변환하기
- reduce()를 사용한 집계 연산 구현
- 자신의 프로젝트에서 반복문을 스트림으로 리팩토링하기
- 병렬 스트림과 순차 스트림의 성능 비교 (1000개 이상 데이터)
- Optional을 활용한 null 안전한 스트림 처리
팁: 스트림 API는 선언적 사고를 요구합니다. “어떻게”보다 “무엇을”에 집중하세요!
댓글