Java Stream 업무 처리 매뉴얼: 현대적인 작성 방식과 성능 한계
기준: Java 17/21/25. Stream API의 핵심 동작은 안정적이지만, 작성 방식과 활용 경계는 현대화해야 합니다.
1. 결과 수집
불변 결과가 필요하면 Stream.toList()를 사용할 수 있고, 변경 가능한 목록이 필요하면 ArrayList로 명시적으로 수집하세요. 모든 collector가 변경 가능한 컬렉션을 반환한다고 가정하지 마세요.
2. 일반적인 경계
Stream은 한 번만 소비할 수 있으며, 단말 연산 후에는 다시 사용할 수 없습니다. toMap은 중복된 key를 만나면 예외를 던지고, groupingBy는 추가 메모리를 사용합니다. null 값과 순서는 미리 정의해 두어야 합니다.
3. 기본적으로 병렬 처리하지 마세요
parallelStream은 공용 ForkJoinPool을 공유하므로, 블로킹 I/O, 트랜잭션 작업, ThreadLocal에 의존하는 로직 또는 엄격한 순서가 필요한 업무에는 적합하지 않습니다. 병렬화하기 전에 데이터 규모, 작업 세분화 정도, 스레드 경합과 하위 단계의 처리 용량을 측정하세요.
4. 적용 원칙
Stream은 순수한 데이터 변환을 표현하는 데 적합하지만, 복잡한 부작용을 숨기는 데는 적합하지 않습니다. map 안에서 데이터베이스 작업을 수행하거나, 메시지를 보내거나, 공유 컬렉션을 수정하지 마세요. 성능이 중요한 경로에서는 직감에 의존하지 말고 JMH를 사용하세요.
5. 점검 목록
short-circuit 연산, primitive stream, 예외 처리, 중첩된 Optional, 컬렉션의 변경 가능성, 반환 순서를 확인하세요. 가독성을 우선하세요. 함수형을 위해 함수형을 추구할 필요는 없습니다.