Search code examples
javajava-streambigdecimal

Parsing an object in stream function


How can I parse String to BigDecimal in the stream function, I would like to keep property set as a String and then parse it to BigDecimal and finally getting the sum of totals by calculating totals taken from each object. (currently on the BigDecimal::add there is a message cannot resolve method add) Thank you.

public Optional<BigDecimal> generalTotalForSingleInvoice(PDDocument pdDocument) {
    return Optional.of(new BigDecimal(findFirst(extractText(pdDocument), INVOICE_GENERAL_TOTAL)
            .replaceAll("\\.", "")
            .replaceAll(",", ".")).stripTrailingZeros());
}

public Optional<BigDecimal> sumOfGeneralTotal(List<PDDocument> document) {
    return document.stream().map(this::generalTotalForSingleInvoice).reduce(BigDecimal.ZERO, BigDecimal::add);

}

Solution

  • You are creating a Stream<Optional<BigDecimal>>, and you can't reduce that Stream with a BinaryOperator<BigDecimal>, so BigDecimal::add doesn't fit.

    Since your generalTotalForSingleInvoice can never return an empty Optional, it has no reason to return an Optional. You can change it to:

    public BigDecimal generalTotalForSingleInvoice(PDDocument pdDocument) {
        return new BigDecimal(findFirst(extractText(pdDocument), INVOICE_GENERAL_TOTAL)
                .replaceAll("\\.", "")
                .replaceAll(",", ".")).stripTrailingZeros();
    }
    

    Now, your original Stream pipeline will work, but note that the reduce variant you are using doesn't return an Optional (since you are passing an identity value), so you should change the return type of the method:

    public BigDecimal sumOfGeneralTotal(List<PDDocument> document) {
        return document.stream().map(this::generalTotalForSingleInvoice).reduce(BigDecimal.ZERO, BigDecimal::add);
    
    }