【精通函数式编程】(三)Lambda表达式原理与函数式接口精讲

简介: 本文讲解lambda表达式语法、语义,讲解函数式接口是什么,作用是什么,Lambda表达式的编译原理,以及Java8及高版本的函数式接口Consumer、Function 、Predicate,将会在工作中大量用到

image.png

前言:

📫 作者简介:小明 java 问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫

🏆 Java 领域优质创作者、阿里云专家博主、华为云享专家🏆

🔥 如果此文还不错的话,还请👍关注点赞收藏三连支持👍一下博主哦

本文导读

本文先通过语法讲解-》引出函数式接口-》Lambda原理解析-》函数式接口精讲,逐步深入

一、Lambda表达式语法精讲lambda是什么?

我们通过前面两篇文章,了解lambda表达式可以理解为一种简洁可传递的匿名函数,没有名称只有->,有参数列表函数的大括号{}(函数主体),还可以有返回值,可传递理解为可以作为参数传递给方法或存储在变量中。

如图是使用lambda表达式,排序代码的语法解析

image.png

Lambda表达式是不能直接使用 System.out.println 打印的 ,可以看到报了 “参数不匹配; *** 不是函数接口”,那什么是函数式接口?

二、函数式接口

image.png

函数式接口简单来说就是,只有一个抽象(abstract)方法的接口( interface),注如果我们只有一个抽象接口,但是有多个默认实现的方法,拿还是函数式接口

用函数式接口我们能做什么?Lambda表达式 说是类似匿名内部类,所以提供的这个抽象方法是作为函数式接口的实例的,可以理解为,Lambda表达式是 函数式接口的一个实现。

run0(() -> {
        System.out.println("执行run()内部逻辑");
    });
    // 由于Runnable中只定义了一个 抽象的 run() 方法,所以run方法就是一个函数式接口
    void run0(Runnable r) {
        r.run();
    }

这段代码很好的诠释了,什么是函数式接口,函数式接口怎么用lambda实现。

三、Lambda表达式原理解析

上面代码经过编译后, .class中共有三个方法,一个默认构造方法,一个main方法,还多了一个我们没有定义过的方法: lambdamain0()显然,这个方法就是lambda表达式内逻辑操作方法,它是一个static的方法。那么,这个lambdamain0()方法是怎么被调用的呢?

image.png

我们通过对java命令指定选项查看底层详细的编译过程:Java在编译时,首先,在实现类的内部,将Lambda表达式,抽取出来作为一个static方法lambdamain0();,然后对Lambda.class(final类)做了默认实现 $Lambda1.class,接下来,执行实现类的main()方法时,就会对lambda表达式利用实现类中的print()方法运行,最后将结果返回并打印。这就是Lambda表达式的底层运行逻辑。如图是上述代码的 .class文件

四、函数式接口详解

就Runnable来说,JavaAPI中实际上给我们提供了很多 函数式接口(例如Runnable、Callable、Comparator),只不过我们很少提及这个概念,Java8及后面高版本中有很多新的函数式接口,例如 Consumer、Function 、Predicate

Predicate:提供了一个test的抽象方法,如果你的lambda表达式,是想返回一个boolean,那可以用这个方法接收

image.png

代码实例如下:

Predicate<OrderInfo> non = orderInfo -> orderInfo.getOrderAmt().compareTo(BigDecimal.valueOf(100)) > 0;
for (OrderInfo orderInfo : orderList)
        if (non.test(orderInfo)) { }

Consumer:该接口定义个一个 accept的抽象方法,没有返回值(void),可以接收任意对象,并对这个对象执行操作

image.png

run(orderInfoList, orderInfo -> { System.out.println("落库"); });
    static void run(List<OrderInfo> orderInfoList, Consumer<OrderInfo> consumer) {
        for (OrderInfo orderInfo : orderInfoList)
            consumer.accept(orderInfo);
    }

Function:接口定义了 apply的,接收任意对象,返回任意对象,使用的时候可以将输入对象的信息映射到输出

image.png

List<CouponInfo> build = build(orderInfoList, orderInfo -> new CouponInfo(orderInfo));
    System.out.println(build.get(0).toString());
    /**
     * 通过订单信息,构件订单使用的优惠信息
     */
    public static List<CouponInfo> build(List<OrderInfo> orderInfoList, Function<OrderInfo, CouponInfo> function) {
        System.out.println("构件CouponInfo");
        List<CouponInfo> couponInfos = new ArrayList<>(orderInfoList.size());
        for (OrderInfo orderInfo : orderInfoList) {
            couponInfos.add(function.apply(orderInfo));
        }
        return couponInfos;
    }
    // 输出:构件CouponInfo  > CouponInfo{orderId='***', orderAmt=***}

小结

本文讲解lambda表达式语法、语义,讲解函数式接口是什么,作用是什么,Lambda表达式的编译原理,以及Java8及高版本的函数式接口Consumer、Function 、Predicate,将会在工作中大量用到

相关文章
|
2月前
|
并行计算 安全 数据处理
函数式编程和面向对象编程有什么区别?
【10月更文挑战第12天】 函数式编程与面向对象编程是两种不同的编程范式。前者强调数学函数的求值、不可变数据和纯函数,后者则以对象为核心,封装数据和方法。函数式编程更关注数据转换和计算过程,而面向对象编程关注对象的定义和交互。两者在数据处理、函数角色、代码结构、并发处理、灵活性和适用场景等方面存在显著差异。在实际开发中,可以根据需求选择合适的编程范式或结合使用。
76 4
|
5月前
|
并行计算 Java API
深入理解Java中的Lambda表达式与函数式接口
【7月更文挑战第19天】在Java 8中引入的Lambda表达式,不仅简化了代码编写,还为函数式编程提供了支持。本文将探讨Lambda表达式的核心概念、其与函数式接口的关系以及如何在Java中高效利用这一特性来提升代码的简洁性和可读性。我们将通过实例分析Lambda表达式的语法规则和常见用法,同时解释函数式接口的设计原则及其在Java标准库中的应用,旨在帮助开发者更好地理解和运用这一强大的工具。
|
5月前
|
Java 开发者
深入理解Java中的Lambda表达式与函数式编程
在Java 8中引入的Lambda表达式,为Java带来了一种全新的编程范式——函数式编程。本文将深入探讨Lambda表达式的概念、语法和实际应用场景,以及它如何改变我们编写和维护代码的方式。通过具体的例子,我们将看到Lambda表达式如何简化代码结构,提高开发效率,并使代码更加简洁易读。最后,我们将讨论Lambda表达式在多线程编程中的应用,以及它对Java开发者技能集的影响。
|
7月前
|
算法 编译器 程序员
【C++入门到精通】 Lambda表达式 C++11 [ C++入门 ]
【C++入门到精通】 Lambda表达式 C++11 [ C++入门 ]
50 1
|
7月前
|
存储 并行计算 算法
Lambda表达式与函数式工具
【5月更文挑战第10天】探索Python的函数式编程:Lambda表达式用于快速定义匿名函数,如求平方;函数式工具如`map()`、`filter()`、`reduce()`简化代码。通过实例展示在数据处理、并行计算中的应用,如匿名函数与`map()`结合实现列表元素运算,`filter()`筛选条件,`reduce()`做累积计算。不可变性和纯函数提升代码可靠性,结合面向对象编程实现代码复用。利用`functools`、`itertools`等模块及第三方库如`toolz`增强函数式编程能力。函数式编程适用于数据处理、并行计算,优点在于清晰、高效和易于维护。
41 0
|
7月前
|
Java 程序员 C#
Lambda表达式:简洁而强大的函数式编程利器
【4月更文挑战第3天】本文探讨了Lambda表达式的基础和在编程中的应用,包括简化代码和提高可读性。Lambda表达式是匿名函数,用于简单的功能,如示例中的平方运算和列表筛选。通过`map`、`filter`等函数,Lambda表达式能有效处理列表操作。文中还展示了Lambda表达式的高级用法,如闭包特性、异常处理及与高阶函数的结合。通过实例,读者可以学习如何利用Lambda表达式实现更高效、简洁的编程。
69 0
|
7月前
|
设计模式 Java 程序员
为什么程序员喜欢用Lambda表达式?
“lambda 表达式”是一段可以传递的代码,因此它可以被执行一次或多次。在学习语法(甚至包括一些奇怪的术语)之前,我们先回顾一下之前在Java 中一直使用的相似的代码块。
61 0
|
算法 编译器 C++
C++11 Lambda表达式的用法与原理
C++11 Lambda表达式的用法与原理
106 0
|
Java API Scala
【JDK新特性】一篇搞懂Lambda表达式 & 函数式接口
【JDK新特性】一篇搞懂Lambda表达式 & 函数式接口
|
Oracle JavaScript Java
函数式编程与Lambda表达式
函数式编程与Lambda表达式