使用Java 8在对象列表中除以十进制值? - java

我有一个具有频率和数量(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())));

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

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 RMI调用Python方法 - java

我有一个通过Python web2py创建的远程方法。如何测试和调用Java中的方法?我能够测试该方法是否实现@service.xmlrpc,但是如何测试该方法是否实现@service.run? 参考方案 如果您能做到,我会感到惊讶。 Java RMI需要Java对等体。

Java Double与BigDecimal - java

我正在查看一些使用双精度变量来存储(360-359.9998779296875)结果为0.0001220703125的代码。 double变量将其存储为-1.220703125E-4。当我使用BigDecimal时,其存储为0.0001220703125。为什么将它双重存储为-1.220703125E-4? 参考方案 我不会在这里提及精度问题,而只会提及数字…

使用Java Spark逐行读取大型文本文件 - java

我正在尝试读取较大的文本文件(2至3 GB)。我需要逐行读取文本文件,并将每一行转换为一个Json对象。我尝试使用.collect()和.toLocalIterator()来读取文本文件。 collect()适用于小文件,但不适用于大文件。我知道.toLocalIterator()会将散布在群集中的数据收集到单个群集中。根据文档,.toLocalIterat…

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…