java - 使用java 8除对象列表中的bigdecimal值?

标签 java lambda java-8 java-stream

我有一个发票对象列表,其属性为频率和金额(BigDecimal)。

1)需要根据频率相乘并更改数量,而不会失去精度。在下面显示的代码中尝试过,但输出失去了一些精度。金额值应为 100。

2) 是否可以使用 java 8 流 API 替换发票列表中的金额值。 尝试使用

invoiceList.forEach(s -> s.getAmount().multiply(new BigDecimal("10")));

但这不会替换对象中的金额值。 在这种情况下无法弄清楚使用replaceAll,尝试了下面的代码但给出了编译错误,

 newList.replaceAll((v) -> v.getAmount().multiply(frequencyFactor.get(v.getFrequency())));

整个主类如下。无法更改任何数据类型或设计。我必须处理从网络服务获取的列表。

public class InvoiceMain {
    public static void main(String[] args) {
        List<Invoice> invoiceList = Arrays.asList(new Invoice("Quarterly", new BigDecimal(300)), new Invoice("Annually", new BigDecimal(1200)));
        Map<String, BigDecimal> frequencyFactor = new HashMap<>();
        frequencyFactor.put("Annually", new BigDecimal(1.0 / 12));
        frequencyFactor.put("Quarterly", new BigDecimal(1.0 / 3));
        for (Invoice invoice : invoiceList) {
            invoice.setAmount(invoice.getAmount().multiply(frequencyFactor.get(invoice.getFrequency())));
        }
        System.out.println(invoiceList);
    }
}

class Invoice {
    private String frequency;
    private BigDecimal amount;

    public Invoice(String frequency, BigDecimal amount) {
        super();
        this.frequency = frequency;
        this.amount = amount;
    }

    public String getFrequency() {
        return frequency;
    }

    public void setFrequency(String frequency) {
        this.frequency = frequency;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    @Override
    public String toString() {
        return "Invoice [frequency=" + frequency + ", amount=" + amount + "]";
    }
}

输出是:

[Invoice [frequency=Quarterly, amount=99.999..], Invoice [frequency=Annually, amount=99.999...]]

所需的输出是

[Invoice [frequency=Quarterly, amount=100], Invoice [frequency=Annually, amount=100]]

最佳答案

该缺陷是将 BigDecimal 构造函数与 double 一起使用。然后 BigDecimal 无法确定精度并使用适合 double 的精度,同时引入了不精确的值(来自 double )。

new BigDecimal(1.0/12)

最好改为随后除以 12:使用 divideBy

Map<String, BigDecimal> divisors = ...
divisors.put("Anually", BigDecimal.valueOf(12));
...
final Map<String, BigDecimal> finalDivisors = divisors;

BigDecimal sum = invoiceList.stream()
    .map(inv -> inv.amount.divideBy(finalDivisors.get(inv.frequency))
    .sum();
<小时/>

在实际代码中:

static class Invoice {
    final BigDecimal amount;
    final int months;

    Invoice(BigDecimal amount, int months) {
        this.amount = amount;
        this.months = months;
    }
}

public static void main(String[] args) {
    List<Invoice> invoices = Arrays.asList(
            new Invoice(new BigDecimal("12.50"), 3),
            new Invoice(new BigDecimal("120.50"), 12),
            new Invoice(new BigDecimal("7.25"), 3));
    BigDecimal sum = invoices.stream()
            .map(inv -> inv.amount.divide(BigDecimal.valueOf(inv.months),
                                          RoundingMode.HALF_UP))
            .reduce(BigDecimal.ZERO, BigDecimal::add);

    System.out.println("Sum: " + sum); // 16.63
}

关于java - 使用java 8除对象列表中的bigdecimal值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44144968/

相关文章:

java - 清除 Swing 中按钮单击操作的文本字段

java - 将 Android 客户端连接到 NodeJS 中的套接字服务器时出错

C++ 在对象中保留 Lambda 表达式

c# - 将表达式解析为参数

lambda - 理解 C++0x lambda 捕获

java - 对象 [id=XYZ] 不是已知的实体类型

Java如何存储不同类型的对象

java - 是否可以在 openJRE 没有 java FX 的环境中运行 JavaFX jar?

security - GRPC Java 的 SSL 错误

collections - Java8 Collectors.groupingBy