컬렉션 처리의 혁신, Java Stream API
Java Stream API는 Java 8에 도입되어 컬렉션을 보다 효율적으로 처리할 수 있도록 지원하며, 지연 평가(lazy evaluation), 병렬 처리(parallelism), 함수형 프로그래밍(functional programming)으로 프로그래머가 깔끔하고 확장 가능한 코드를 작성할 수 있게 돕습니다. 이는 데이터 필터링, 변환, 집계 작업을 간소화하여 개발자가 컬렉션을 다루기 더욱 쉽게 합니다.
주요 개념: 지연 평가
지연 평가는 스트림 작업을 효과적으로 수행하는 데 핵심 역할을 합니다. 이는 중간 연산이 최종 연산이 호출될 때까지 실행되지 않는다는 것을 의미합니다.
- 중간 연산 (예: filter(), map()): 입력 스트림을 다른 스트림으로 변환하지만, 실제 결과를 생성하는 것은 최종 연산전까지 지연됩니다.
- 최종 연산 (예: forEach(), findFirst()): 스트림의 요소를 소비하여 결과를 제공합니다.
아래는 지연 평가의 예제입니다:
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5)
.filter(num -> {
System.out.println("Filtering: " + num);
return num % 2 == 0;
})
.map(num -> {
System.out.println("Mapping: " + num);
return num * 2;
});
System.out.println("스트림 파이프라인 정의됨, 아직 실행되지 않음.");
stream.forEach(System.out::println);
병렬 스트림의 활용
병렬 스트림은 멀티 코어 프로세서를 활용해 스트림을 여러 청크로 나누고 이를 병렬로 처리합니다. parallelStream()
메소드나 기존 스트림에 parallel()
을 호출하여 병렬 스트림을 생성할 수 있습니다.
- 적합한 시나리오: 대용량 데이터 세트 및 CPU 집약적인 작업에 적합합니다. 그러나 I/O 바운드 작업과 작은 데이터 세트에서는 병렬 스트림 사용을 피하는 것이 좋습니다. 오버헤드로 인해 성능 이점이 없을 수 있습니다.
람다에서의 변수 스코프
람다 표현식은 주변 스코프의 변수를 캡처할 수 있지만, 이는 해당 변수가 final 또는 사실상 final일 때만 가능합니다.
int factor = 2;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.map(n -> n * factor)
.forEach(System.out::println);
결론
Stream API는 요소의 순차적 처리를 위한 강력한 도구입니다. 이것을 올바르게 사용하면 가독성이 향상되고, 반복적인 코드가 줄어들며, 성능이 개선될 수 있습니다. 지연 평가, 병렬 스트림의 활용, 람다에서의 변수 스코프를 이해하는 것이 Stream API를 효과적으로 활용하는 데 있어 중요합니다.
출처 : 원문 보러가기