Search code examples
javaintellij-ideajava-streambigdecimal

IntelliJ hint while rounding BigDecimal division stream result


I have a little bit strange problem with IntelliJ hint while dividing result at the end of stream operation.

products.stream()
        .filter(
            order ->
                order.getEstimatedRealizationDate().compareTo(begin) > 0
                    && order.getEstimatedRealizationDate().compareTo(end) < 0)
        .map(order -> order.getProduct().getPrice())
        .reduce(ZERO, BigDecimal::add)
        .divide(valueOf(productList.size()))
        .setScale(3, RoundingMode.CEILING);

Regardless of how you set the rounding, IntelliJ constantly claims that the dividing operation may carry a risk in the form of ArtithmeticException in the form of a message and backlighting divide operation. I was using either round() option.

Reports calls to divide() or setScale() without a rounding mode argument. Such calls can lead to an ArithmeticException when the exact value cannot be represented in the result (e.g. because it has a non-terminating decimal expansion). Specifying a rounding mode prevents the ArithmeticException.

I have the impression that I've tried every possible variant, but still, IntelliJ doesn't give up. Please suggest what I'm doing wrong. Thanks in advance for each kind of help.


Solution

  • setScale just returns a BigDecimal object with the specified scale. You want to use the overloaded divide method

    divide(BigDecimal divisor, int scale, RoundingMode roundingMode):

    products.stream()
            .filter(
                order ->
                    order.getEstimatedRealizationDate().compareTo(begin) > 0
                        && order.getEstimatedRealizationDate().compareTo(end) < 0)
            .map(order -> order.getProduct().getPrice())
            .reduce(ZERO, BigDecimal::add)
            .divide(valueOf(productList.size()), 3, RoundingMode.CEILING);
    

    In this example I am using RoundingMode.CEILING but here are the docs for RoundingMode in case you want to use a different rounding mode.