Programming/Java

java stream BigDecimal add 합계 구하는 방법

Jan92 2023. 7. 19. 22:24

java stream을 통해 BigDecimal 합계 또는 연산하는 방법

 

java stream BigDecimal add

부동소수점의 부정확성으로 인해 java에서는 소수점에 대한 정확한 계산이 요구되거나 화폐 단위를 사용할 때 BigDecimal 타입을 사용하는데요.

해당 포스팅은 'java에서 stream을 활용하여 BigDecimal을 연산하는 방법'에 대해 정리한 내용입니다.

 

 


코드 예시

List<BigDecimal> bigDecimalList = Arrays.asList(
        BigDecimal.valueOf(1.123),
        BigDecimal.valueOf(0.335),
        BigDecimal.valueOf(2.10101),
        BigDecimal.valueOf(0.54321)
);

//stream을 사용하지 않는 경우 연산
BigDecimal sum = BigDecimal.ZERO;
for (BigDecimal eachValue : bigDecimalList) {
    sum = sum.add(eachValue);
}

다음과 같은 BigDecimal List가 있을 때 stream을 사용하지 않는다면 예시와 같이 for문 내부에서 add 메서드를 통해 연산을 수행할 수 있는데요.

 

//reduce 메서드 내부에서 람다식 사용
BigDecimal sum = bigDecimalList.stream().reduce(BigDecimal.ZERO, (x, y) -> x.add(y));

//reduce 메서드 내부에서 사용되던 람다식을 메서드 참조 형식으로 사용
BigDecimal sum = bigDecimalList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

Stream과 Stream의 reduce() 함수를 사용하게 되면 다음과 같이 코드를 조금 더 간결하게 사용할 수 있습니다.

 

 

***

reduce() 함수는 stream의 요소들을 하나의 데이터로 만드는 작업을 수행하는데요.

아래 3가지 파라미터를 받을 수 있으며, 위에서 사용된 함수는 identityaccumulator를 인자로 받는 경우입니다.

 

T identity : 계산에 적용할 초기값으로 사용할 요소를 넣습니다. 스트림이 비어 있더라도 초기값을 반환합니다.

BinaryOperator<T> accumulator : BinaryOperator는 T 타입의 인자 두 개를 받고, T 타입의 객체를 리턴하는 함수형 인터페이스입니다.

BinaryOperator<U> combiner : 병렬 스트림에서 각 스레드의 결과를 합치데 사용되는 기능입니다.

 

T reduce(T identity, BinaryOperator<T> accumulator);

 

 


코드 예시 (객체 내부 BigDecimal의 경우)

@Setter
@Getter
@AllArgsConstructor
public class Invoice {

    String invoiceNo;
    BigDecimal unitPrice;
    int quantity;
}

(예시에 사용할 Invoice Class)

 

List<Invoice> invoiceList = Arrays.asList(
        new Invoice("a001", BigDecimal.valueOf(20.9), 2),
        new Invoice("a002", BigDecimal.valueOf(5.15), 4),
        new Invoice("a003", BigDecimal.valueOf(12.19), 3),
        new Invoice("a004", BigDecimal.valueOf(3.999), 1)
);

//메서드 내부에서 람다식 사용
BigDecimal sum = invoiceList.stream().map(invoice -> invoice.getUnitPrice()).reduce(BigDecimal.ZERO, (x, y) -> x.add(y));

//람다식을 메서드 참조 형식으로 사용
BigDecimal sum = invoiceList.stream().map(Invoice::getUnitPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

예시와 같이 객체 내부의 BigDecimal을 연산할 때는 map() 메서드를 통해 BigDecimal 변수만 꺼내서 reduce() 메서드를 사용하면 되는데요.

 

//unitPrice x quantity 값을 더하고 싶은 경우
BigDecimal sum = invoiceList.stream().map(invoice -> invoice.getUnitPrice().multiply(BigDecimal.valueOf(invoice.getQuantity())))
        .reduce(BigDecimal.ZERO, BigDecimal::add);

개당 가격(unitPrice) x 수량(qutntity) 값을 더하고 싶은 경우 다음과 같이 map으로 만들 때 계산을 하고 reduce()를 적용할 수도 있습니다.

 

 

 

< Java, BigDecimal을 사용해야 하는 이유 >

2022.08.18 - [Programming/Java] - Java - BigDecimal 사용하는 이유 (feat.부동소수점의 부정확성)

 

 

< 참고 자료 >
https://www.baeldung.com/java-stream-reduce

https://stackoverflow.com/questions/22635945/adding-up-bigdecimals-using-streams