利用Stream聚合函数如何对BigDecimal求和

 更新时间:2023年05月29日 16:35:10   作者:SUDDEV  
这篇文章主要介绍了利用Stream聚合函数如何对BigDecimal求和问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

利用Stream聚合函数对BigDecimal求和

数据库查找的结果经常会有List等集合,而集合中存放法是JAVA对象,对象中存在BigDecimal的字段,如果用for或者iterator遍历来累加感觉很麻烦,stream聚合函数很好的解决了这个问题.做个笔记mark一下

POJO

package test;
import java.math.BigDecimal;
/**
 * 用户实体类
 *
 * @author suddev
 * @create 2018-02-26 上午11:03
 **/
public class User {
    private long id;
    private BigDecimal money;
    public User(long id, BigDecimal money) {
        this.id = id;
        this.money = money;
    }
    // getter&setter
}

在实体类中,我们可以看到实体存在一个为BigDecimal的money属性,以计算所有查询出来的用户金钱总额为例子:

package test;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
 * 测试类
 *
 * @author suddev
 * @create 2018-02-26 上午11:03
 **/
public class Test {
    public static void main(String[] args) {
        // 准备数据
        List<User> userList = new ArrayList<User>();
        for (int i = 0; i < 100; i++) {
            User user = new User(i,new BigDecimal(i+"."+i));
            userList.add(user);
        }
        // for version
        BigDecimal result1 = BigDecimal.ZERO;
        for (User user : userList) {
            result1 = result1.add(user.getMoney());
        }
        System.out.println("result1 = "+result1);
        // java 8 stream version
        BigDecimal result2 = userList.stream()
                // 将user对象的mongey取出来map为Bigdecimal
                .map(User::getMoney)
                // 使用reduce聚合函数,实现累加器
                .reduce(BigDecimal.ZERO,BigDecimal::add);
        System.out.println("result2 = "+result2);
    }
}
  • map是一个对于流对象的中间操作,通过给定的方法,它能够把流对象中的每一个元素对应到另外一个对象上,这里将user对象的money取出来map为Bigdecimal
  • reduce是一个终结操作,它能够通过某一个方法,对元素进行削减操作。该操作的结果会放在一个Optional变量里返回。可以利用它来实现很多聚合方法比如count,max,min等。

这里利用了reduce的第二个方法重载

Treduce(T identity, BinaryOperator accumulator);

第一个参数是我们给出的初值,第二个参数是累加器,可以自己用实现接口完成想要的操作,这里使用Bigdecimal的add方法

最后reduce会返回计算后的结果

Stream流,求和计算

Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作。通常我们需要多行代码才能完成的操作,借助于Stream流式处理可以很简单的实现。 

将分别使用传统的foreach 和 stream流 进行集合的求和汇总运算,废话不多说,直接上代码 

创建测试的实体类

@Data
@ToString
public class Sys_testClass implements Serializable {
    private String name;//名称
    private double price;//价格
    private int number;//数量
    private double sum_price;//商品总价格
}

插个题外话,上面的 @Date和@ToString 注解代替了我们自动生成的getting,setting和toString方法,让类看上去更简洁明了,并且当你重新添加或删除字段的时候,不用去管getting,setting方法,大大节省了开发时间及效率,如果想用的小伙伴,直接导入 lombok依赖即可

创建 Main方法

并且往集合中添加测试数据

public static void main(String[] args) {
    List<Sys_testClass> listTest = new ArrayList<>();
    Sys_testClass test1 = new Sys_testClass();
    test1.setName("商品1");
    test1.setPrice(3200.0);
    test1.setNumber(3);
    test1.setSum_price(test1.getPrice()*test1.getNumber());
    listTest.add(test1);
    Sys_testClass test2 = new Sys_testClass();
    test2.setName("商品2");
    test2.setPrice(1599.0);
    test2.setNumber(6);
    test2.setSum_price(test2.getPrice()*test2.getNumber());
    listTest.add(test2);
    Sys_testClass test3 = new Sys_testClass();
    test3.setName("商品3");
    test3.setPrice(999.0);
    test3.setNumber(2);
    test3.setSum_price(test3.getPrice()*test3.getNumber());
    listTest.add(test3);
}

 利用传统foreach循环遍历

得到集合中所有价格的和,代码如下

double sum_price=0.00; //价格总和的初始值
for (Sys_testClass sys_testClass : listTest) {
    sum_price+=sys_testClass.getSum_price();//循环相加 集合中的总价格
}
System.err.println(sum_price);// 打印输出值为: 21192.0

利用java8新特性(Stream流)遍及集合

只需要一行代码

double sum_price = listTest.stream().mapToDouble(Sys_testClass::getSum_price).sum();
System.err.println(sum_price);//打印输出值为: 21192.0

注:价格是double 类型,所以这里用了mapToDouble方法,如果是int类型求和 替换成 mapToInt方法即可

两者相比可以看出传统循环需要 4 行代码,而新特性只需要 1 行代码,速度上其实一样的,底层都是循环遍历得到结果,但是集合多了,开发时间就将会大大节省 

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JAVA宝藏工具hutool的使用

    JAVA宝藏工具hutool的使用

    开发过程中总是会遇到需要自己自定义工具类的情况,做一些数据转换、字符串操作、日期处理、加解密、编解码、金额计算等,本文就详细的介绍有一个工具类hutool的使用,感兴趣的可以了解一下
    2021-10-10
  • 重新实现hashCode()方法

    重新实现hashCode()方法

    hashCode()是Java中的一个重要方法,用于计算对象的哈希码。本文介绍了如何重新实现hashCode()方法,包括使用对象的属性计算哈希码、使用字符串拼接计算哈希码、使用随机数计算哈希码等方法。同时,还介绍了如何避免哈希冲突,提高哈希表的效率。
    2023-04-04
  • 如何为Spark Application指定不同的JDK版本详解

    如何为Spark Application指定不同的JDK版本详解

    这篇文章主要给大家介绍了关于如何为Spark Application指定不同的JDK版本的相关资料,文中通过示例代码将解决的方法介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友下面来随着小编一起学习学习吧。
    2017-11-11
  • SpringBoot中的MongoTemplate的各种条件查询示例详解

    SpringBoot中的MongoTemplate的各种条件查询示例详解

    这篇文章主要介绍了SpringBoot中的MongoTemplate的各种条件查询示例详解,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借价值,需要的朋友参考下吧
    2024-01-01
  • Spring Properties的使用和配置方法

    Spring Properties的使用和配置方法

    这篇文章主要介绍了Spring Properties的使用和配置方法,本文不是原理分析、源码分析文章,只是希望可以帮助读者更好地理解和使用 Spring Properties,有兴趣的可以了解一下
    2018-01-01
  • Springboot事件监听与@Async注解详解

    Springboot事件监听与@Async注解详解

    这篇文章主要介绍了Springboot事件监听与@Async注解详解,在开发中经常可以利用Spring事件监听来实现观察者模式,进行一些非事务性的操作,如记录日志之类的,需要的朋友可以参考下
    2024-01-01
  • 解决Java项目启动报错:Logback configuration error detected:问题

    解决Java项目启动报错:Logback configuration error detected:问题

    这篇文章主要介绍了解决Java项目启动报错:Logback configuration error detected:问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • SpringBoot深入分析讲解监听器模式上

    SpringBoot深入分析讲解监听器模式上

    监听器模式,大家应该并不陌生,主要的组成要素包括了事件、监听器以及广播器;当事件发生时,广播器负责将事件传递给所有已知的监听器,而监听器会对自己感兴趣的事件进行处理
    2022-07-07
  • 基于spring boot实现一个全局异常处理器

    基于spring boot实现一个全局异常处理器

    在项目开发中,我们可以基于spring boot提供的切面特性,来很轻松的实现全局异常的处理,所以本文主要为大家介绍了如何基于spring boot实现一个全局异常处理器,有需要的可以参考下
    2023-09-09
  • springMVC几种页面跳转方式小结

    springMVC几种页面跳转方式小结

    本篇文章主要介绍了springMVC 几种页面跳转方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02

最新评论