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>

  

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

  

  未完待续。。。

  

原文地址:https://www.cnblogs.com/xxzhuang/p/8288486.html

时间: 2024-10-06 00:40:54

Java8函数式接口以及lambda表达式实践的相关文章

Java 关于函数式接口与Lambda表达式之间的关系

java是一种面向对象的语言,java中的一切都是对象,即数组,每个类创建的实例也是对象.在java中定义的函数或方法不可能完全独立,也不能将方法函数作为参数或返回值给实例. 在java7及以前,我们一直都是通过匿名内部类把方法或函数当做参数传递,如下是一个线程实例. @Test public void testAnonymous() { new Thread(new Runnable() { @Override public void run() { System.out.println("匿

java反射-Method中的invoke方法的用法-以及函数式接口和lambda表达式

作者最近研究框架底层代码过程中感觉自己基础不太牢固,于是写了一点案例,以防日后忘记 接口类:Animals 1 public interface Animals { 2 3 public void eat(); 4 } package cn.chenc.study.entity; public interface InterfaceFactory { public String show(int i); } 实体类:Person package cn.chenc.study.entity; im

Java8新特性之lambda表达式

lambda表达式 简化实例化函数式接口(functional interface)的过程 lambda表达式的优势 简化代码的实现 lambda表达式的语法 一个 Lambda 表达式可以有零个或多个参数 参数的类型既可以明确声明,也可以根据上下文来推断.例如:(int a)与(a)效果相同 所有参数需包含在圆括号内,参数之间用逗号相隔.例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c) 空圆括号代表参数集为空.例如:() -> 42

Java 函数式编程和Lambda表达式

1.Java 8最重要的新特性 Lambda表达式.接口改进(默认方法)和批数据处理. 2.函数式编程 本质上来说,编程关注两个维度:数据和数据上的操作. 面向对象的编程泛型强调让操作围绕数据,这样可以实现以类为单位的重用,当为类添加新的数据类型时,原有代码无需修改. 函数式编程是一种不同的编程模型,它以操作(函数)为中心,强调变量不变性.函数式编程的准则是不依赖外部的数据,也不改变外部数据的值.这一特性满足了多核并行程序设计的需求,因此能简化并行程序开发. 函数式编程用函数来表达所有的概念,完

java8(一)Lambda表达式

其实很久前已经学习过了Lambda表达式,但是学习后没有多少使用的机会,久而久之也就忘记(惭愧).最近新的项目用的jdk8所以准备再学习一次,写下文章也是为了记录,方便以后再忘的时候,不用到处找资料(旁白:这么丢人的事,能别到处说吗). 语法 (参数) -> 表达式 或 (参数) -> {表达式} 第一个Lambda表达式 public class Java8Lambda { @Test public void test1() { // lambda表达式 Greeting helloLamb

Java函数式编程(Lambda表达式)小记

函数式编程 函数式编程(Functional Programming)是编程范式的一种.最常见的编程范式是命令式编程(Impera Programming),比如面向过程.面向对象编程都属于命令式编程,大家用得最多.最熟悉.函数式编程并非近几年的新技术或新思维,其诞生已有50多年时间. 在函数式编程里面,一切都是数学函数.当然,函数式编程语言里也可以有对象,但这些对象是不可变的——要么是函数参数要么是返回值.函数式编程语言里没有for等循环,而是通过递归.把函数当成参数传递的方式实现循环效果.

java代码之美(14)---Java8 函数式接口

Java8 函数式接口 之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁. 一.概念 1.什么是函数式接口 概念 所谓的函数式接口, 当然首先是一个接口, 然后就是在这个接口里面 只能有一个抽象方法. 有关函数式接口,有个专门的注解叫:@FunctionalInterface.该注解主要特点有: 1.该注解只能标记在"有且仅有一个抽象方法"的接口上,表示函

Java核心技术-接口、lambda表达式与内部类

本章将主要介绍: 接口技术:主要用来描述类具有什么功能,而并不给出每个功能的具体实现.一个类可以实现一个或多个接口. lambda表达式:这是一种表示可以在将来的某个时间点执行的代码块的简洁方法. 内部类机制:内部类定义在另一个类的内部,其中的方法可以访问包含它们的外部类的域. 代理:一种实现任意接口的对象. 1 接口 1.1 接口的概念 概念:接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义. "如果类遵从某个特定的接口,那么就履行这项服务": Arrays

Java8函数式接口/Lambda表达式/接口默认方法/接口静态方法/接口冲突方法重写/lambda表达式指定泛型类型等

一:函数式接口 1.函数式接口的概念就是此接口必须有且只能有一个抽象方法,可以通过@FunctionalInterface来显示规定(类似@Override),但是没有此注解的但是只有一个抽象方法的接口也是函数式接口:(接口也和类一样有包访问权限,但是内部的方法则默认是public) @FunctionalInterface public interface IFoo{ void print(); }  // 就是一个最简单的函数式接口,但是如果再有个如void print2()抽象方法则这个接