궁금증 연구소

안녕하세요. 궁금증연구소입니다.

오늘 포스팅 주제는 "[java] IntStream.iterate()와 Stream.iterate()의 차이점은?"입니다.

 

프로그래머스의 콜라츠 수열 만들기를 풀고, 다른 사람의 풀이를 봤는데 이상한 점이 있어 포스팅을 해봅니다.

 

첫번째 풀이

먼저 위 풀이를 보면, IntStream의 iterate를 활용해서 1보다 큰 값인 경우에 반복하도록 Stream을 만들고, IntStream concat을 활용해서 스트림 내에 1을 따로 추가해 주었습니다.

 

그 이유는 IntStream.iterate()는 두 번째 파라매터인 조건식이 false를 리턴하자마자 stream이 끝나기 때문입니다.

위 코드에서 값의 흐름을 보면 

 

값의 흐름

 

2까지만 스트림에 포함되는 것을 알 수 있습니다. 왜냐하면 2 가 1이 된 값은 조건식이 false가 리턴되어, 스트림에 포함되지 못하고 바로 다음 작업으로 넘어가기 때문입니다. i  -> i>=1로 작성하면 될 거 같지만, 무한루프에 빠져버립니다. 

outofmemoryerror

 

자바 공식문서를 보면 hasNext가 false를 리턴하자마자 스트림이 끝난다고 명시되어 있습니다.

 

IntStream.iterate() java 공식문서

 

 

반면 두 번째 코드를 한번 살펴보겠습니다.

 

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이 포함되어 있습니다.

 

java공식문서 설명

공식문서를 봐도 비슷하게 설명이 되어 있네요. 

 

 

인자 작동방식의 차이
작동방식의 차이

 

 

위와 같이 같아 보이는 Iterate() 함수에도 차이가 있으니, 차이를 명확히 인지하고 사용해야

버그 없는 코드 작성에 도움이 될 듯합니다.

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading