Java 8과 Java 9의 iterate() 메서드 차이
Java 8에서 Stream API의 iterate() 메서드는 seed(초기값)와 단항 연산자(UnaryOperator)를 인수로 받습니다. 이렇게 생성된 스트림은 기본적으로 무한(infinite)스트림이므로, 개발자가 limit(), findFirst(), findAny() 같은 연산을 활용해 명시적인 종료 조건을 직접 추가해야 했습니다.
반면 Java 9부터는 iterate() 메서드에 새로운 인수인 Predicate가 추가되었습니다. 이 Predicate에 스트림을 중단할 조건을 전달하면, 별도의 limit() 호출 없이도 자연스럽게 스트림을 종료할 수 있습니다.
메서드 시그니처(Syntax)
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
각 인수의 의미
- seed : 스트림의 첫 번째 요소가 되는 초기값
- hasNext : 다음 요소를 계속 생성할지 판단하는 종료 조건(Predicate)
- next : 이전 요소를 기반으로 다음 요소를 생성하는 함수(UnaryOperator)
예제 코드
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.List;
public class StreamIterateMethodTest {
public static void main(String args[]) {
List<Integer> numbers1 = Stream.iterate(1, i -> i + 1) // 인수 2개 (Java 8 방식)
.limit(10)
.collect(Collectors.toList());
System.out.println("Java 8: " + numbers1);
List<Integer> numbers2 = Stream.iterate(1, i -> i <= 10, i -> i + 1) // 인수 3개 (Java 9 방식)
.collect(Collectors.toList());
System.out.println("Java 9: " + numbers2);
}
}
실행 결과(Output)
Java 8: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Java 9: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
정리
두 방식 모두 동일한 결과를 출력하지만, Java 9의 3개 인수 버전은 종료 조건이 메서드 내부에 포함되어 코드가 훨씬 간결하고 가독성이 높습니다. 특히 limit() 호출을 누락해 발생할 수 있는 무한 루프 위험을 사전에 차단할 수 있다는 점에서 실무적으로 큰 장점입니다.