for문과 stream

Jisu_M·2024년 11월 21일

프로젝트를 진행하면서, 특정 작업에서 for문을 사용한 코드가 가독성이 떨어지고 유지보수가 어려운 점을 발견!

특히, 리스트의 각 요소에 대해 반복적인 연산을 하는 부분에서 이를 더 간결하게 바꾸고자 Stream API를 활용하여 함수형 프로그래밍 스타일로 리팩토링을 진행했다.

🔍 문제 상황: 상품 가격 계산

주문 카트에 담긴 상품들의 수량과 가격을 계산하여 전체 가격을 구하는 부분
기존에는 for문을 사용하여 반복적으로 연산을 했지만, 코드가 길어지고 가독성이 떨어졌다.

아래는 for문을 사용한 기존 코드이다.

BigDecimal totalPrice = BigDecimal.ZERO;
for (OrderCart cart : orderCartList) {
    BigDecimal price = BigDecimal.valueOf(cart.getQuantity())
                    .multiply(cart.getProduct().getPrice());
    totalPrice = totalPrice.add(price);
}

위 코드에서 주문 카트에 담긴 모든 상품의 가격을 계산하기 위해 각 카트의 수량과 가격을 곱한 후, 그 값을 누적하여 totalPrice를 구했다.

❗️이렇게 구현한 경우

  1. BigDecimal 객체의 multiply()와 add() 메서드가 여러 번 사용되어 중복되는 코드
  2. 가독성: 로직이 복잡하고, 계산 과정이 명확하게 분리되지 않음
  3. 추후 계산 방식이 변경되거나, 필터링 조건이 추가될 경우, for문 내부의 로직을 수정해야 함

위의 문제를 해결하기 위해 Stream API를 활용해 코드의 가독성을 높였다.

BigDecimal totalPrice = orderCartList.stream()
        .map(cart -> BigDecimal.valueOf(cart.getQuantity())
                .multiply(cart.getProduct().getPrice())) // 수량과 가격 곱셈
        .reduce(BigDecimal.ZERO, BigDecimal::add); // 총합 계산
  1. orderCartList 리스트를 Stream으로 변환

  2. 각 OrderCart 객체에 대해 map() 함수를 사용해, 수량과 가격을 곱한 BigDecimal 값을 반환합니다. (map()은 스트림의 각 요소를 변환할 때 사용)

  3. reduce() 함수는 스트림의 모든 값을 하나로 결합하는 작업을 한다. 여기서는 BigDecimal.ZERO를 초기값으로 설정하고, BigDecimal::add를 사용해 모든 가격을 더하여 결과적으로 전체 금액이 totalPrice에 저장된다.

이렇게 for문을 사용한 반복문 코드에서 Stream을 활용하여 코드의 가독성을 높이고, 유지보수를 용이하게 만들었다.

stream은 병렬 처리(parallelStream)을 지원하기 때문에 대량의 데이터에서 성능 향상이 가능한 장점도 있으니 프로젝트에 맞게 사용해 보려고 한다.

profile
개발 여정을 기록하며 성장하는 매일

0개의 댓글