zoukankan      html  css  js  c++  java
  • Java8函数式接口以及lambda表达式实践

    最近重新深入了解和学习了Java8的函数式接口以及lambda表达式,发现以前写的代码大多都是伪-函数表达式,因此重新精炼了一下的这部分代码,仅供参考,如有更好的方式,欢迎在评论区留言。

      1.计算订单总金额

      订单总金额一般是在后台循环叠加每个购买商品的金额已获取到,通常的方式如下

         BigDecimal totalAmount = new BigDecimal(0);
         for (VenditionProduct venditionProduct : venditionVo.getVenditionProductList()) { totalAmount = totalAmount.add(venditionProduct.getPrice()); }

      用lambda的方式如下

            BigDecimal totalPrice = venditionVo.getVenditionProductList().stream().map(VenditionProduct::getPrice).reduce(BigDecimal::add).orElse(BigDecimal.ONE);

      2.循环集合组装新的类

      面对的场景是更新字段,下面将出现一个更新方法updateNotNull,该方法是一个通用方法,仅更新不为字段null的属性,由于venditionProduct中只允许Product的price和sellAmount属性,因此不能直接将前端传递过来的集合直接进行更新,需要提取这两个属性重新组装成新的类。

      比较Low的做法如下(伪-函数表达式)

    复制代码
            venditionProductList.forEach(venditionProduct -> {
                VenditionProduct newVenditionProduct = new VenditionProduct();
                newVenditionProduct.setId(venditionProduct.getId());
                newVenditionProduct.setSellAmount(venditionProduct.getSellAmount());
                newVenditionProduct.setPrice(venditionProduct.getPrice());
                updateNotNull(newVenditionProduct);
            });
    复制代码

      以下是真-函数表达式

     venditionProductList.stream().map(venditionProduct ->
                    VenditionProduct.build(venditionProduct.getId(), venditionProduct.getSellAmount(), venditionProduct.getPrice()))
                    .forEach(this::updateNotNull);

      3.在枚举中的应用

      我们有如下的枚举类

    复制代码
      public enum RecordTypeEnum {
            /**
             * 0为手工入库  1生产入库  2手工出库   4 退货入库
             */
            MANUAL_STORE(0),
            PRODUCE_STORE(1),
            MANUAL_OUT(2),
            VENDITION_OUT(3),
            REFUND_IN(4),;
            private final int type;
    
            RecordTypeEnum(int type) {
                this.type = type;
            }
        }
    复制代码

      遇到的场景可能是希望通过type查找对应的枚举值

      通常的方式是

    复制代码
     public static RecordTypeEnum getRecordTypeEnum(int type) {
            for (RecordTypeEnum typeEnum :
                    RecordTypeEnum.values()) {
                if (typeEnum.getType() == type) {
                    return typeEnum;
                }
            }
            return null; 
        }
    复制代码

      Java8中我们可以这样子做  

     public static RecordTypeEnum getRecordTypeEnum1(int type) {
            return Arrays.stream(RecordTypeEnum.values()).filter(recordTypeEnum -> recordTypeEnum.getType() == type).findFirst().orElse(null);
        }

       还有我们可能需要获取对应的数组

     public String[] getEnumStringArray() {
            return Arrays.stream(RecordTypeEnum.values()).map(Enum::name).toArray(String[]::new);
        }

       4.编写一行的lambda语法有助于提高代码的健壮性(这里的重点不是lambda的使用技巧,但是觉得有必要记录一下)

      面对的业务场景是增加生产产品的生产计划表(plan),一张计划表可以有多个产品,一个产品需要一或者多个原料组成,因此关系是一对多对多,下面看一下我最先的写的代码(伪-函数表达式)

      重点关注最后的一个方法,最初的实现是这样子的

      

      这里的问题有两个,一是简短的 lambda 表达式能提高代码可读性,这是函数式编程的重要好处之一,这里完全忽视了这一点,二是planProduct(产品)和planMaterial(原料)是关联在一起的,也就是说增加原料这个操作,应该封装在增加产品这个操作里面,修改后的代码如下

      这里做记录的原因是在将lambda表达式精简成一行代码的同时,需要不断的调整代码的结构,使之朝向更加的稳定健壮的方向发展,原本的代码逻辑虽然过程也易懂,但是又丑又长,担当了太多的任务。

       5.根据已知类型集合转换成另一个类型的集合

      大致逻辑是获取生产产品相关联的原料(包括规格),实际是上就是需要根据List<ProductMaterail>转换成List<PlanMaterial>

      

      这里的做法还是犯了跟上面一条同样的错误,后面调整如下

      

  • 相关阅读:
    如何选择合适的MySQL存储引擎
    如何提高Windows操作系统内存利用效率
    jQuery插件 面包屑导航
    [Fireworks+Dreamweaver制作网站]第7课上
    一次完整的安全渗透测试
    jquery插件 跟随屏幕滚动的层
    [Fireworks+Dreamweaver制作网站]第1课
    [Fireworks+Dreamweaver制作网站]第2课
    随笔 幸福
    jQuery插件 jqueryflexselect下拉框自动提示
  • 原文地址:https://www.cnblogs.com/itrena/p/8289530.html
Copyright © 2011-2022 走看看