java 8 函数式接口_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的做法如下(伪-函数表达式)

48304ba5e6f9fe08f3fa1abda7d326ab.png

venditionProductList.forEach(venditionProduct -> {

VenditionProduct newVenditionProduct = new VenditionProduct();

newVenditionProduct.setId(venditionProduct.getId());

newVenditionProduct.setSellAmount(venditionProduct.getSellAmount());

newVenditionProduct.setPrice(venditionProduct.getPrice());

updateNotNull(newVenditionProduct);

});

48304ba5e6f9fe08f3fa1abda7d326ab.png

以下是真-函数表达式

venditionProductList.stream().map(venditionProduct ->

VenditionProduct.build(venditionProduct.getId(), venditionProduct.getSellAmount(), venditionProduct.getPrice()))

.forEach(this::updateNotNull);

3.在枚举中的应用

我们有如下的枚举类

48304ba5e6f9fe08f3fa1abda7d326ab.png

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;

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

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

通常的方式是

48304ba5e6f9fe08f3fa1abda7d326ab.png

public static RecordTypeEnum getRecordTypeEnum(int type) {

for (RecordTypeEnum typeEnum :

RecordTypeEnum.values()) {

if (typeEnum.getType() == type) {

return typeEnum;

}

}

return null;

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

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),一张计划表可以有多个产品,一个产品需要一或者多个原料组成,因此关系是一对多对多,下面看一下我最先的写的代码(伪-函数表达式)

8252e52c06de332f9a18b8ed43c5a5c2.png

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

b100f157e60bbb5167550f67b4a77299.png

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

f28e19bcd446b9f6150662fef79b4fb2.png

d101e80ab4cfed10575eb0b395e52733.png

21a63044ed4e96a0b763ad996e96d496.png

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

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

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

676bcdfaae5b866c2b95841ec5ae01b3.png

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

47613012fdc97d7f529e5a737c12ed7e.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值