java 函数式接口编程和stream实践总结

近日老大急忙忙部置了一项任务,要求从10月1号起,从几十张账单表中,生成下面的交易统计数据

1、每个商户入网累计金额,累计笔数,最高单笔交易金额,

2、单笔超过3000元的交易次数,单笔交易金额超过3000的合计金额

3、然后2000到3000的交易金额和笔数

4、1000到2000的交易金额和笔数

5、小于1000的交易金额和笔数

可以看出2、3、4、5数据其实只是条件不一样,就是过滤出的条件不一样,数据格式是一样的。这样用jdk8新的函数式接口来实现。

现在把解决方案流程作一下回顾

1、首先是按照商户获取账单

2、根据账单进行计算

3、把计算后的结果保存到数据库

 

我们这边重点讲一下根据账单计算。获取的账单用List<Gt> gts表示,Gt表示账单表,有交易金额tradeMoney关键字段,

analyse是要计算后要保存到数据库的对象。

现在说一下每个统计字段怎么计算

 

累计金额

int tradeMoney = gts.stream().mapToInt(Gt::getTradeMoney).sum();
analyse.setMoneyTotal(CommonUtils.transferMoney(tradeMoney));

累计笔数

gts.size()

最高单笔交易金额

Optional<Gt> optional = gts.stream().max(Comparator.comparing(Gt::getTradeMoney));

optional.ifPresent(item -> analyse.setMoneyMax(CommonUtils.transferMoney(item.getTradeMoney())));

 

这边用到了optional对象,可以避免非空判断,读者如果不了解,请自行百度。

下面是重点了,先贴代码

           // >=3000
            setData(gts, (a) -> a >= 3000 * 100, analyse, GtBillMemberAnalyse::setMoney1, GtBillMemberAnalyse::setNum1);
            // 2000>= and < 3000
            setData(gts, (a) -> a < 3000 * 100 && a >= 2000 * 100, analyse, GtBillMemberAnalyse::setMoney2, GtBillMemberAnalyse::setNum2);
            // 1000>= and <2000"
            setData(gts, (a) -> a < 2000 * 100 && a >= 1000 * 100, analyse, GtBillMemberAnalyse::setMoney3, GtBillMemberAnalyse::setNum3);
            // <1000
            setData(gts, (a) -> a < 1000 * 100, analyse, GtBillMemberAnalyse::setMoney4, GtBillMemberAnalyse::setNum4);

可以看出来,单笔超过3000元等逻辑被抽象成Lambda表达式了,分别是

 (a) -> a >= 3000 * 100, analyse

 (a) -> a < 3000 * 100 && a >= 2000 * 100

等。

保存值被抽象成方法引用GtBillMemberAnalyse::setMoney1, GtBillMemberAnalyse::setNum1等,如果 不了解,请百度Java8之方法引用

下面是setData方法代码

    /**
     * 设置交易金额和笔数
     *
     * @param gts
     * @param predicate 过滤函数
     * @param analyse 保存的对象
     * @param funcMoney 设置金额
     * @param funcNum  设置笔数
     */
    private void setData(List<Gt> gts, IntPredicate predicate, GtBillMemberAnalyse analyse, BiConsumer<GtBillMemberAnalyse, BigDecimal> funcMoney, BiConsumer<GtBillMemberAnalyse, Integer> funcNum) {
        int totalmoney = gts.stream().mapToInt(Gt::getTradeMoney).filter(predicate).sum();
        int num = (int) gts.stream().mapToInt(Gt::getTradeMoney).filter(predicate).count();
        // 金额
        funcMoney.accept(analyse, CommonUtils.transferMoney(totalmoney));
        // 笔数
        funcNum.accept(analyse, num);

    }

这个变得非常简单,只有4行代码,却实现了统计计算,判断逻辑把抽象成IntPredicate,设置值被抽象成BiConsumer。

具体这些怎么使用,请百度相关文档,本篇不是入门文章

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值