[Java/프로그래머스] 두 정수 사이의 합 - 스트림 사용하여 알고리즘 리팩토링하기

김하밍·2024년 6월 21일

Java

목록 보기
46/46

처음 제출한 코드

class Solution {
    public long solution(int a, int b) {
        long sum = 0;
        for (int i = ((a < b) ? a : b); i <= ((a < b) ? b : a); i++) {
            sum += i;
        }
        
        return sum;
    }
}

스트림 사용하여 리팩토링한 코드

class Solution {
	public long solution(int a, int b) {
    	return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b))
        .asLongStream()
        .sum();
    }
}

해당 함수는 int 타입의 매개변수 2개를 입력받지만, long 타입을 반환하도록 정해져 있습니다.
int형의 두 수 사이의 모든 값을 합산하는 과정에서 발생할 수 있는 오버플로우를 방지하기 위해 long 타입을 사용하여 반환하는 이유인 것 같습니다.

  1. IntStream.rangeClosed() 를 사용하여 두 정수 사이의 모든 값을 포함하는 스트림을 생성했습니다.
  2. rangeClosed() 내부에는 Math.min(a, b) 를 선언하여 a, b 중 작은 수를 찾고, Math.max(a, b) 를 선언하여 a, b 중 큰 수를 찾는 기능을 활용했습니다.
  3. .asLongStream() 을 사용하여 IntStreamLongStream 으로 변환합니다. 합산(연산)하여 담길 수가 int 범위를 넘어가게 되면 타입 안정성이 보장되어 정확한 계산이 되도록 하기 위함입니다.
  4. sum() 을 사용하여 스트림의 모든 값을 합산합니다.

스트림 사용 후기

처음에는 기본적인 for 루프와 삼항 연산자를 사용하여 코드를 작성했습니다. 문제없는 코드이지만, 반복문을 통한 합산은 한 눈에 계산하기 어려워 코드의 가독성을 떨어뜨릴 수 있으므로, 스트림 API명을 통해 코드의 가독성과 간결성을 높이기 위해 리팩토링을 하게 되었습니다.

스트림은 Java의 Stream API를 사용하여 컬렉션이나 배열 등의 데이터 소스를 처리하는 데 사용됩니다.

특히, 반복문과 인덱스 변수의 사용을 줄이게 되어 코드의 목적이 더 명확하게 드러났다고 느꼈습니다.
스트림 API는 함수형 프로그래밍 스타일을 지원하므로, 코드의 선언적 접근 방식을 촉진해볼 수 있었습니다. 이러한 접근 방식은 유지보수와 확장에 있어서도 더 유리한 구조를 제공할 수 있습니다.
스트림을 사용하여 long 타입으로 변환하는 과정에서 발생할 수 있는 오버플로우 문제를 예방할 수 있었습니다. 이 과정은 입력받을 값들이 int형이기 때문에 반복적인 합산을 위해서는 꼭 미리 해줘야 하는 설정이었습니다.

함수형 프로그래밍의 장점을 극대화할 수 있는 스트림을 사용하면 선언적 데이터 처리와 병렬 처리를 쉽게 구현할 수 있음을 느꼈습니다.

스트림 API와 람다식 함께 사용할 때의 장점

필요하다면 람다식과 함께 사용하여 스트림 API와 함께 사용될 때의 장점을 극대화시킬 수도 있습니다.

위의 예제에서는 복잡한 코드가 없어서 사용하지 않았지만, 람다식은 익명 함수를 간결하고 명확하게 표현할 수 있는 방법을 제공하기 때문에 불필요한 코드 작성을 줄일 수 있습니다.

예시)

List<String> names = Arrays.asList("John", "Jane", "Doe");
List<String> filteredNames = names.stream()
                                  .filter(name -> name.startsWith("J"))
                                  .collect(Collectors.toList());
profile
나만의 언어로 기록하며 성장하기 !

0개의 댓글