[java] 스트림 최종 연산에서의 연산 순서에 대한 설명

스트림은 자바 8부터 도입된 기능으로, 컬렉션 요소를 처리하기 위한 강력한 기능을 제공합니다. 스트림은 중간 연산과 최종 연산으로 구성되며, 최종 연산은 스트림을 평가하고 결과를 반환하는 역할을 담당합니다.

스트림 최종 연산에서의 연산 순서는 중요한 요소입니다. 이것은 스트림에 적용되는 많은 중간 연산이 있다면 최종 연산을 수행하기 전에 중간 연산이 완료되어야 함을 의미합니다.

예를 들어서, 다음과 같은 코드로 숫자 리스트의 제곱값을 출력하는 스트림을 생성하고 최종 연산을 수행한다고 가정해봅시다.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

numbers.stream()
       .map(n -> n * n)
       .forEach(System.out::println);

위 예제에서는 map 중간 연산을 사용하여 리스트의 각 요소를 제곱값으로 변환하고(n -> n * n) 해당 값을 출력하는 최종 연산인 forEach를 수행합니다. 중간 연산 map은 스트림의 모든 요소에 적용되고, 최종 연산 forEach는 변환된 값들을 출력합니다.

스트림은 내부적으로 최적화되어 있기 때문에 중간 연산은 가능한 한 게으르게(evaluated lazily) 처리됩니다. 다시 말해, 중간 연산은 최종 연산이 호출될 때까지 해당 요소를 실제로 처리하지 않습니다. 이는 코드의 성능을 향상시켜주는 장점을 제공합니다.

따라서, 위 예제에서 mapforEach는 순차적으로 실행되지만, 중간 연산 map의 결과값들은 실제로 사용될 때까지 계산되지 않습니다. 이후 최종 연산 forEach가 호출될 때 비로소 중간 연산의 결과값들이 실제로 출력됩니다.

스트림 최종 연산의 순서는 중간 연산들의 게으른 처리 방식과 함께 프로그래머의 의도에 따라 유동적으로 결정됩니다. 따라서, 스트림을 사용하는 개발자는 중간 연산과 최종 연산의 순서를 적절하게 조정하여 필요한 데이터 처리를 수행할 수 있도록 유의해야 합니다.

참고 자료: