lambda表达式的进阶过程

news2024/11/26 14:42:13

文章目录

  • 什么是Lambda表达式
    • 简述
    • Lambda表达式的优点
    • 语法格式
  • 函数式接口
    • 定义
    • 常见的函数式接口
    • 汇总
  • Lambda的演化过程
    • lambda表达式简化
  • 总结

什么是Lambda表达式

简述

Lambda表达式是JAVA8中提供的一种新的特性,是一个匿名函数方法。可以把Lambda表达式理解为一段可以传递的代码,可以写出更简洁、更灵活的代码。

Lambda表达式的优点

  1. 简洁:无需像匿名内部类那样写大量模板代码,直接把方法体的实现写进去即可。
  2. 灵活:Lambda可以作为参数和返回值进行传递,赋值给函数式接口。
  3. 可推导:可以根据上下文推导出参数和返回值的类型,不需要显式声明。
  4. 惰性:只有调用了该lambda表达式,才会真正执行方法体中的代码。

语法格式

(parameters) -> expression

(parameters) ->{ statements; }

第一个为无返回值的语法,第二个为有返回值的语法。
使用lambda表达式可以写出非常简洁的函数式代码,经常用于集合迭代,事件处理等场景。

函数式接口

定义

任何接口,如果只包含一个抽象方法,那么它就是一个函数式接口。

interface ILove{
    void love(int a,String b);
}

对于函数式接口,我们可以通过lambda表达式来创建该接口的对象

常见的函数式接口

几个常见的函数式接口:

  • Runnable:抽象方法run()
  • Supplier:抽象方法get()
  • Consumer:抽象方法accept()
  • Function:抽象方法apply()
  • Predicate:抽象方法test()

汇总

  1. 函数式接口就是仅包含一个抽象方法的接口。
  2. 使用 @FunctionalInterface 注解进行修饰,明确其角色。
  3. 函数式接口的抽象方法形式称为函数描述符。
  4. 可以包含默认方法和静态方法。
  5. 描述符参数列表和返回值相同不构成重复。
  6. 可以继承自其他接口。
  7. 函数式接口的实现可以通过 Lambda 表达式简洁地表示。
  8. 常用的函数式接口:Consumer、Supplier、Function、Predicate 等。
  9. 可以用方法引用直接引用现有方法实现函数式接口。
  10. 在许多场景下可用函数式接口替代匿名内部类。
  11. 作为方法的参数和返回值传递 Lambda 实现。
  12. 扩展了 Java 对函数式编程的支持。
  13. 但不应滥用函数式接口,应与面向对象编程结合使用。
  14. Java 中函数式接口的定义让 Lambda 表达式有了使用场景。
  15. 使语言表达更灵活,代码更简洁。
    总结起来,函数式接口和 Lambda 表达式相辅相成,增强了 Java 的函数式编程能力,使代码更加简洁高效。但还需与面向对象编程结合使用,发挥各自优势。

Lambda的演化过程

描述:有一个接口,我们需要实现其方法。
方式一:普通方法,直接普通类实现,并重写方法

public class Testlambda {
    public static void main(String[] args) {
        ILove love=new Love();
        love.love(2);
    }


}

class Love implements ILove{

    @Override
    public void love(int a) {
        System.out.println("I Love You"+a);
    }
}

interface ILove{
    void love(int a);
}

方式二:静态内部类

public class Testlambda {
   static class Love implements ILove{

        @Override
        public void love(int a) {
            System.out.println("I Love You"+a);
        }
    }

    public static void main(String[] args) {
        ILove love=new Love();
        love.love(2);
    }

}

interface ILove{
    void love(int a);
}

方式三:局部内部类

public class Testlambda {


    public static void main(String[] args) {
        //局部内部类
        class Love implements ILove{

            @Override
            public void love(int a) {
                System.out.println("I Love You"+a);
            }
        }
        
        ILove love=new Love();
        love.love(2);
    }


}

interface ILove{
    void love(int a);
}

方式四:匿名内部类

public class Testlambda {


    public static void main(String[] args) {
        //匿名内部类
        ILove love=new ILove(){
            @Override
            public void love(int a) {
                System.out.println("I Love You"+a);
            }
        };
        love.love(2);
    }
    
}

interface ILove{
    void love(int a);
}

方式五:lambda表达式

public class Testlambda {


    public static void main(String[] args) {
        //lambda表达式
        ILove love=(int a)-> {
                System.out.println("I Love You"+a);
            };

        love.love(2);
    }

}

interface ILove{
    void love(int a);
}

通过以上5中方式的对比,可以看到从繁琐到简单的一个过程,每一种都在上一种的基础上进行演化。演化到一种相对简单的形式,供用户使用。

lambda表达式简化

未简化前:
在这里插入图片描述
简化一:去掉参数类型

public class Testlambda {


    public static void main(String[] args) {
        //lambda表达式
        ILove love;
        love=( a)-> {
            System.out.println("I Love You"+a);
        };
        love.love(2);
    }

}

interface ILove{
    void love(int a);
}

简化二:去掉括号

public class Testlambda {


    public static void main(String[] args) {
        //lambda表达式
        ILove love;
        love= a-> {
            System.out.println("I Love You"+a);
        };
        love.love(2);
    }

}

interface ILove{
    void love(int a);
}

简化3:去掉花括号,前提是花括号中只有一行

public class Testlambda {


    public static void main(String[] args) {
        //lambda表达式
        ILove love;
        love= a-> System.out.println("I Love You"+a);
        
        love.love(2);
    }

}

interface ILove{
    void love(int a);
}

注:

  1. lambda表达式只能由一行代码的情况,才能简化为一行,如果由都澳航那么就用代码块包裹
  2. 前提是接口为函数式接口
  3. 多个参数也可以去掉参数类型,要去掉,都去掉,不能带一个去一个

总结

  1. Lambda表达式实质上是一个可传递的匿名函数,可以实现函数式编程。
  2. 语法形式为:(参数列表) -> {代码体},去掉了方法名称、返回值声明等代码模板。
  3. Lambda通常用来传递给函数式接口的参数或赋值给函数式接口变量。
  4. 使用Lambda能避免创建匿名内部类,代码更简洁。
  5. Lambda可以访问外层作用域的变量,这称为闭包。
  6. Lambda表达了一个块的代码,也可以直接用于调用,称为代码块。
  7. Lambda可以延迟执行,只有被调用时才会执行。
  8. 常用的函数式接口如Consumer、Supplier、Function等。
  9. 可以用方法引用来直接引用已有的方法实现,更简洁。
  10. Lambda靠Java的类型推断来判断参数和返回类型。
  11. Lambda让Java加入了函数式编程的特性,可以写出更简洁、灵活的代码。
  12. 但也不能过度使用Lambda,需要区分应用场景,与面向对象编程结合使用。
    总之,Lambda表达式让Java语言表达能力更强,编程风格更灵活,对于集合、流、事件驱动等编程场景都很有用。但还是要适度使用,与面向对象编程结合,发挥它的优势。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/794177.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于uniapp中的日历组件uni-calendar中的小红点

关于uniapp中的日历组件uni-calendar中的小红点 如果你使用过uni-calendar组件,可能你觉得这个小红点有点碍眼,但是官方给定的日历组件uni-calendar中如果你想要在某一天上添加一些信息例如:价格,签到,打卡之类,只要标…

【PWN · ret2text | 伪rand()】[HDCTF 2023]pwnner

伪随机数以及ctypes库的初步接触 目录 前言 一、题目 二、解题思路 三、exp 总结 前言 一道简单的ret2text,加上一些伪随机的知识,对于本蒟蒻萌新来说,比较新,值得记录。 一、题目 栈溢出保护、PIE保护都没有开。反汇编后…

servlet银行储蓄管理系统java存取转账交易 jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 servlet银行储蓄管理系统 系统有1权限:管…

python与深度学习(四):ANN和fashion_mnist二

目录 1. 说明2. fashion_mnist的ANN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测…

Guitar Pro有没有免费的?

Guitar Pro是一款功能强大的吉他谱编辑软件,它为音乐创作者和乐手提供了极大的便利。但是,许多人对于Guitar Pro是否有免费版本,问题存在疑虑。下面我们就来详细介绍Guitar Pro有没有免费的内容吧! 一、Guitar Pro有没有免费的 …

音视频——视频流H264编码格式

1 H264介绍 我们了解了什么是宏快,宏快作为压缩视频的最小的一部分,需要被组织,然后在网络之间做相互传输。 H264更深层次 —》宏块 太浅了 ​ 如果单纯的用宏快来发送数据是杂乱无章的,就好像在没有集装箱 出现之前,…

MultipartFile类型接收上传文件报出的UncheckedIOException以及删除tomcat临时文件失败源码探索

1、描述异常背景: 因为需要分析数据,待处理excel文件的数据行数太大,手动太累,花半小时写了一个定制的数据入库工具,改成了通用的,整个项目中的万级别数据都在工具上分析,写SQL进行分析&#x…

Rust vs Go:常用语法对比(十)

题图来自 Rust vs. Golang: Which One is Better?[1] 182. Quine program Output the source of the program. 输出程序的源代码 package mainimport "fmt"func main() { fmt.Printf("%s%c%s%c\n", s, 0x60, s, 0x60)}var s package mainimport "fm…

【C语言】嵌入式C语言项目管理利器:深入理解Makefile的应用与实践

目录 一、makedile的概述 1、案例引入 2、makefile 3、Makefile优点 二、makefile的语法规则 1、语法规则 2、简单实战 三、makefile的变量 1、自定义变量 2、系统环境变量 3、预定义变量 4、高级makefile 一、makedile的概述 1、案例引入 gcc a.c b.c c.c ‐o …

Error: Please select Android SDK解决方案(仅供参考)

一、问题描述 今天开始正式接触项目的工作内容,然后从组里的代码仓库里git clone了一份Android Studio项目下来。下好了以后我使用Android Studio打开这个项目,但在尝试编译运行的时候遇到了很多错误。例如,开发环境界面上面用于编译的小锤子…

【MySQL】基本查询(插入查询结果、聚合函数、分组查询)

目录 一、插入查询结果二、聚合函数三、分组查询(group by & having)四、SQL查询的执行顺序五、OJ练习 一、插入查询结果 语法: INSERT INTO table_name [(column [, column ...])] SELECT ...案例:删除表中重复数据 --创建…

ARM汇编中类似c语言中宏定义的使用

—# 一、是什么? .equ xxx,xxx 类似c语言中#define xxx xxxx ## 1.操作例子 代码如下(示例): .equ bss_start,0x2000 .equ bss_end,0x20000x100 .global _start _start:ldr r0,bss_startldr r1,bss_end

用ChatGPT的AI配音插件,1秒获取想要的语音样本

Hi! 大家好,我是专注于AI项目实战的赤辰,今天继续跟大家介绍另外一款GPT4.0插件Speechki。 一、什么是Speechki? Speechki是一个专门的文本转语音(TTS)工具,它的主要功能是将文本转换为高质量的音频文件。…

【C++初阶】 priority_queue(优先级队列)

⭐博客主页:️CS semi主页 ⭐欢迎关注:点赞收藏留言 ⭐系列专栏:C初阶 ⭐代码仓库:C初阶 家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我…

wordpress我的个人网站搭建

WordPress介绍 WordPress是一个功能强大且易于使用的网站管理平台。它是基于PHP和MySQL构建的,可以在各种不同的主机上运行。 wordpress对服务器的要求 需求最低版本要求PHP7.4 或更高版本MySQL5.6 或更高版本Web服务器任意(如:Apache、Ng…

【Nodejs】登录鉴权-Cookie

1.什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时,就打卡成功&…

read_table()函数--Pandas

1. 函数功能 将通用定界符文件读取到DataFrame中 2. 函数语法 pandas.read_table(filepath_or_buffer, *, sep_NoDefault.no_default, delimiterNone, headerinfer, names_NoDefault.no_default, index_colNone, usecolsNone, dtypeNone, engineNone, convertersNone, true…

java并发编程 13:JUC之Semaphore、CountdownLatch、 CyclicBarrier

目录 Semaphore使用常见应用原理源码流程 CountdownLatch使用原理 CyclicBarrier使用 Semaphore 使用 Semaphore是一种计数信号量,它用于控制对共享资源的访问。它维护了一个许可计数器,表示可用的许可数量。线程在访问共享资源前必须先获得许可&#…

小学期笔记——天天酷跑2

程序的錯誤一共是3個維度 1:編譯錯誤 (1)点击后边的红色点点 (2)鼠标移动红线上 (3)复制错误提示内容 (4)粘贴到CHATGPT (5) 复制爆红正行(全文&#xff0…

JavaScript function默认参数赋值前后顺序差异

1、(num1,num2num1) 当传值仅传一个参数时,先给到第一个参数即num1,num1再赋值给num2, function sum(num1, num2 num1) {console.log(num1 num2) } sum(10)//20 sum(10,3)//13 2、(t2t1,t1) 当传值仅有一个参数时,先给到第一个…