使用Java 8实现BigDecimal对象的求和

x33g5p2x  于2022-09-17 转载在 Java  
字(2.6k)|赞(0)|评价(0)|浏览(6779)

使用java 8 Stream.reduce()方法简化BigDecimal对象的求和。

详细视频笔记

从本质上讲,BigDecimals 是不可变的,这意味着一旦创建了对象,就无法对其进行修改,因此在执行算术运算时,它们并不是那么友好或高效。有许多处理原语的库,例如 Guava's math utilities,但在本教程中,我们将展示 java 8 如何简化从集合中对一系列 BigDecimal进行求和。

数据设置

从 Maven 原型创建一个项目并将其导入 Eclipse,我们将更新 junit。初始化一个 BigDecimals 类型的 Arraylist,我们将在 setUp 方法中添加总和为 15 的元素。

List<BigDecimal> bigDecimalsValues = new ArrayList<>();

@Before
public void setUp () {
    bigDecimalsValues.add(new BigDecimal(1));
    bigDecimalsValues.add(new BigDecimal(2));
    bigDecimalsValues.add(new BigDecimal(3));
    bigDecimalsValues.add(new BigDecimal(4));
    bigDecimalsValues.add(new BigDecimal(5));

}

原生java实现

让我们回顾一下在 java 8 (5, 6, 7) 之前的 java 版本中这是什么样子的。您将需要创建一个对象来存储总和值并使用 for 循环遍历 ArrayList。当您调用 .add 时,它会生成一个新对象,我们需要在其中设置 addBigDecimals 等于结果。使用 junit 断言语句,我们将验证结果是否等于 15。

@Test
public void add_big_decimals_java() {

    BigDecimal addBigDecimals = new BigDecimal(0);

    for (BigDecimal value : bigDecimalsValues) {
        addBigDecimals = addBigDecimals
                .add(new BigDecimal(value.intValue()));
    }

    assertEquals(new BigDecimal(15), addBigDecimals);
}

使用java 8实现

Java 8 引入了终端操作,例如平均、求和、最小、最大和计数,它们以自己的方式包装通用 Stream.reduce。将 arraylist 转换为流将使我们能够调用传入 BigDecimal.ZERO 作为标识的通用 reduce 方法和 BigDecimal::add 累加器方法。

@Test
public void add_big_decimals_java8() {

    BigDecimal sumOfBigDecimals = bigDecimalsValues.stream().reduce(
            BigDecimal.ZERO, BigDecimal::add);

    assertEquals(new BigDecimal(15), sumOfBigDecimals);
}

删除空值

接下来,如果您正在处理 BigDecimal 列表中的空值,当您尝试将它们全部加在一起时,您很可能会遇到 NullPointerException。使用流,我们可以在归约操作之前过滤空值以避免错误。如果您还没有使用 java 8,您可以使用 guava 并从您的数组列表中过滤空引用。

@Test
public void add_big_decimals_java8_null() {

    bigDecimalsValues.add(null);

    BigDecimal sumOfBigDecimals = bigDecimalsValues.stream()
            .filter(Objects::nonNull)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

    assertEquals(new BigDecimal(15), sumOfBigDecimals);
}

对象字段求和

在我们的最后一个片段中,我们将对 BigDecimal 类型的给定对象的字段求和。首先,我们将创建一个对象 Car,该对象具有类型为 BigDecimal 的字段英里。将里程声明为 BigDecimal 是出于演示目的,因为您可能不会在现实世界中这样做。接下来,我们将使用菱形运算符添加 Car 对象来初始化一个列表。需要注意的是,我们添加了一个空Car对象,并使用空英里值初始化了一个Car对象。

一旦我们向Car对象添加值,我们将需要编写代码来使用 java 8 语法对列表中的所有值求和。请记住,我们首先需要过滤 null Car 和里程设置为 null 的Car对象。接下来调用 .map 并返回 BigDecimals 的流,就像以前一样,将减少值并对元素求和。

class Car {

    private BigDecimal miles;

    public Car(BigDecimal miles) {
        super();
        this.miles = miles;
    }

    public BigDecimal getMiles() {
        return miles;
    }

    public void setMiles(BigDecimal miles) {
        this.miles = miles;
    }
}

@Test
public void add_big_decimals_java8_object() {

    List<Car> vehicles = new ArrayList<>();
    vehicles.add(null);
    vehicles.add(new Car(null));
    vehicles.add(new Car(new BigDecimal("10")));
    vehicles.add(new Car(new BigDecimal("20")));

    BigDecimal sumOfBigDecimals = vehicles.stream()
            .filter(Objects::nonNull)
            .filter(c -> c.getMiles() != null)
            .map(Car::getMiles)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

    assertEquals(new BigDecimal(30), sumOfBigDecimals);
}

相关文章

微信公众号

最新文章

更多