안녕하세요. 궁금증연구소입니다.
오늘 포스팅 주제는 "[java] IntStream.iterate()와 Stream.iterate()의 차이점은?"입니다.
프로그래머스의 콜라츠 수열 만들기를 풀고, 다른 사람의 풀이를 봤는데 이상한 점이 있어 포스팅을 해봅니다.
먼저 위 풀이를 보면, IntStream의 iterate를 활용해서 1보다 큰 값인 경우에 반복하도록 Stream을 만들고, IntStream concat을 활용해서 스트림 내에 1을 따로 추가해 주었습니다.
그 이유는 IntStream.iterate()는 두 번째 파라매터인 조건식이 false를 리턴하자마자 stream이 끝나기 때문입니다.
위 코드에서 값의 흐름을 보면
2까지만 스트림에 포함되는 것을 알 수 있습니다. 왜냐하면 2 가 1이 된 값은 조건식이 false가 리턴되어, 스트림에 포함되지 못하고 바로 다음 작업으로 넘어가기 때문입니다. i -> i>=1로 작성하면 될 거 같지만, 무한루프에 빠져버립니다.
자바 공식문서를 보면 hasNext가 false를 리턴하자마자 스트림이 끝난다고 명시되어 있습니다.
반면 두 번째 코드를 한번 살펴보겠습니다.
import java.util.*;
import java.util.stream.Stream;
class Solution {
public int[] solution(int n) {
return Stream.iterate(n, i -> i >= 1, i -> i == 1 ? 0 : i % 2 == 0 ? i / 2 : 3 * i + 1)
.mapToInt(Integer::intValue).toArray();
}
}
같은 iterate 함수이고 조건에 1이 포함된 식을 적었지만, concat 작업 없이 바로 형변환을 통해 값이 도출해 낼 수 있었습니다. 이 스트림에는 1이 포함되어 있습니다.
공식문서를 봐도 비슷하게 설명이 되어 있네요.
위와 같이 같아 보이는 Iterate() 함수에도 차이가 있으니, 차이를 명확히 인지하고 사용해야
버그 없는 코드 작성에 도움이 될 듯합니다.
Java에서 왜 public을 갖는 클래스는 파일단 하나로 제한할까? (0) | 2023.08.11 |
---|---|
자바복습 개념정리#1 (0) | 2023.08.10 |
[Java] Locale.Root 사용하는 이유 (0) | 2023.05.12 |
[Java] IntStream의 map 메소드와 Stream<Integer>의 map 메소드의 차이 (1) | 2023.05.10 |
[java] 와일드카드의 쓸모:: 읽을수 있으나, 쓸수 없다(vice-versa) (0) | 2023.04.10 |