Java中的Lambda表达式

lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。

1.lambda表达式的语法

eg:有如下lambda表达式:

(int a, int b) -> {return a+b};

这个表达式的本质是一个函数。

一般的函数类似如下:

int add(int a, int b) {return a+b;
}

有返回值、方法名、参数列表、方法体。

而Lambda表达式只有参数列表和方法体:

(参数列表)->{方法体}

说明:

  • () :用来描述参数列表;

  • {} :用来描述方法体;

  • -> :Lambda运算符可以叫做箭头符号,或者 goes to(指向);

2.函数式接口

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口叫做函数式接口。

通过使用lambda表达式展示应用场景。

public class Lambda {public static void main(String[] args) {If1 if1 = ()->{System.out.println("无参无返回值");};//调用方法if1.test();If2 if2 = (int a)->{System.out.println("单个参数无返回值:a = " + a);};if2.test(2);If3 if3 = (int a, int b)->{System.out.println("两个参数无返回值:a + b = " + (a + b));};if3.test(1, 2);If4 if4 = ()->{return 4;};System.out.println("无参有返回值,返回值为:" + if4.test());If5 if5 = (int a)->{return a;};System.out.println("有参有返回值,返回值为:a = " + if5.test(5));}//无参无返回值interface If1 {void test();}//单个参数无返回值interface If2{void test(int a);}//两个参数无返回值interface If3{void test(int a, int b);}//无参有返回值interface If4{int test();}//有参有返回值interface If5{int test(int a);}
}

运行结果如图:

在这里插入图片描述

关于如下代码的问题:

        If1 if1 = ()->{System.out.println("无参无返回值");};//调用方法if1.test();

在上述代码中,If1不是一个接口吗?为什么能够有对象if1呢?

实际上这里是使用了lambda来实现匿名内部类的作用,如下:

        If1 if1 = new If1() {@Overridepublic void test() {System.out.println("无参无返回值");}};//调用方法if1.test();

而匿名内部类写成正常的实现类就是类实现If1接口然后创建if1类对象,代码如下:

//定义接口
interface If1{void test();
}
//实现了接口的类
class NiMing implements If1{void test() {System.out.println("无参数无返回值")}
}
//创建类对象
public class Test{NiMing if1 = new NiMing();
}

3.lambda表达式精简语法

  • 参数类型可以省略

  • 假如只有一个参数,()括号可以省略

  • 如果方法体只有一条语句,{}大括号可以省略

  • 如果方法体中唯一一条语句是return返回语句,那么省略大括号的同时return也要省略(只省略return,不省略整个return语句)

    实例代码如下:

public class Lambda2 {public static void main(String[] args) {//无参数()括号不能省略If1 if1 = ()->{System.out.println("无参无返回值");};//调用方法if1.test();//单个参数,参数类型和()括号可以省略//方法体内单个语句{}大括号可以省略If2 if2 = a-> System.out.println("单个参数无返回值:a = " + a);if2.test(2);If3 if3 = (a, b)-> System.out.println("两个参数无返回值:a + b = " + (a + b));if3.test(1, 2);//省略return和{}大括号If4 if4 = ()->4;System.out.println("无参有返回值,返回值为:" + if4.test());If5 if5 = a->a;System.out.println("有参有返回值,返回值为:a = " + if5.test(5));}//无参无返回值interface If1 {void test();}//单个参数无返回值interface If2{void test(int a);}//两个参数无返回值interface If3{void test(int a, int b);}//无参有返回值interface If4{int test();}//有参有返回值interface If5{int test(int a);}
}

运行结果如下:

在这里插入图片描述

4.方法引用

有时候多个lambda表达式实现的函数是一样的话,可以封装成通用方法,以便于维护;

这个时候可以用方法引用实现:

语法是:对象::方法

假如是static静态方法,可以直接 类名::方法

4.1非静态方法的方法引用

示例代码如下:

public class Lambda3 {public static void main(String[] args) {If if1 = a -> a-2;System.out.println("if1的返回值为: " + if1.test(3));If if2 = a -> a-2;System.out.println("if2的返回值为: " + if2.test(4));}//单个参数有返回值interface If{int test(int a);}
}

可以看到两个对象调用的是同一种方法,所以可以使用方法引用来替代,代码如下:

public class Lambda3 {public static void main(String[] args) {
//        If if1 = a -> a-2;
//        System.out.println("if1的返回值为: " + if1.test(3));
//
//        If if2 = a -> a-2;
//        System.out.println("if2的返回值为: " + if2.test(4));//创建对象Lambda3 lambda3 = new Lambda3();//利用lambda表达式引用方法If if1 = lambda3::testA;System.out.println("if1的返回值为: " + if1.test(3));If if2 = lambda3::testA;System.out.println("if2的返回值为: " + if2.test(4));}public int testA(int a) {return a-2;}//单个参数有返回值interface If{int test(int a);}
}

实际上testA实现的也是接口If中的方法。

4.2静态方法的方法引用

直接使用 类名::方法

public class Lambda4 {public static void main(String[] args) {//利用lambda表达式引用方法If if1 = Lambda4::testA;System.out.println("if1的返回值为: " + if1.test(3));If if2 = Lambda4::testA;System.out.println("if2的返回值为: " + if2.test(4));}//静态方法public static int testA(int a) {return a-2;}//单个参数有返回值interface If{int test(int a);}
}

5.构造方法引用

如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用。

语法: 类名::new

实例代码如下:

首先定义一个Dog类:

public class Dog {private String name;private int age;//无参构造方法public Dog(){}//有参构造方法public Dog(String name, int age) {this.name = name;this.age = age;}public String getName() {return this.name;}public int getAge() {return this.age;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
//重写toString方法public String toString() {return "Dog{" + "name='" + name + '\'' +", age=" + age + '}';}
}

然后测试构造方法引用:

public class Lambda5 {public static void main(String[] args) {
//        //传统方法
//        //无参
//        DogService1 dog1 = () -> {
//          return new Dog();
//        };
//        System.out.println(dog1.getDog());
//        //简化版本
//        DogService1 dog1 = () -> new Dog();
//        System.out.println(dog1.getDog());//构造方法引用//无参DogService1 dog1 = Dog::new;System.out.println(dog1.getDog());//有参DogService2 dog2 = Dog::new;System.out.println(dog2.getDog("小汪", 1));}interface DogService1{Dog getDog();   //无参}interface DogService2{Dog getDog(String name, int age);   //有参}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android问题笔记四十八:蓝牙obtainMessage数据传输部分数据丢失乱序问题

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分…

SQL Sever 复习笔记【一】

SQL Sever 基础知识 一、查询数据第1节 基本 SQL Server 语句SELECT第2节 SELECT语句示例2.1 SELECT - 检索表示例的某些列2.2 SELECT - 检索表的所有列2.3 SELECT - 对结果集进行筛选2.4 SELECT - 对结果集进行排序2.5 SELECT - 对结果集进行分组2.5 SELECT - 对结果集进行筛选…

差分阻抗90Ω±10%或者其他分别走什么阻抗

差分阻抗90Ω10%或者其他分别走什么阻抗 普通走线阻抗HDMI接口布线要求USB接口布线要求网口接口布线要求LCD 接口布线要求DDR3关键信号处理要点 普通走线阻抗 必须选择 PCB 走线阻抗来匹配使用中的所有逻辑系别的特性阻抗(对于 CMOS 和 TTL,特性阻抗的范围是 80~11…

模板引擎详解

📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 🌤️动态页面的渲染方式 …

WordPress(10)解决中文连接问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、修改的前后二、自定义结构讲明三、修改方法前言 提示:这里可以添加本文要记录的大概内容: 1.中文连接如:http://www.lplovemm.love/2023/11/12/测试 2.这种连接在提交sitemap收录的时…

C++调用python: VS2017 + Anaconda + pypi第三方库

步骤一:在Anaconda中创建虚拟环境 这一点对大家来说应该很简单,简单介绍一下,不做过多解释。值得注意的是,要用conda命令创建环境,用pip install配置环境。 conda create -n c_python_env python3.9 # 用conda创建pyt…

在ubuntu虚拟机上安装不同版本的交叉编译工具链

在之前的章节中,学习了如何安装了4.8.3的交叉编译工具链: 交叉编译 和 软硬链接 的初识(面试重点)-CSDN博客 但是,在之后学习内核编译时,由于我的树莓派内核版本较高,为6.1,所以在…

Java SpringBoot Controller常见写法

文章目录 环境Controller调用脚本运行结果总结 环境 系统: windows 11 工具: java, idea, git bash Controller 接口常见有以下几种方式 其中: Tobj 调用脚本 我的是windows 系统,使用 git bash 窗口运行, 用 cmd 或者 power shell 会有问题 curl …

传统算法:使用 Pygame 实现二分查找

使用 Pygame 模块实现了二分查找的动画演示。首先,它生成一个有序数组,并通过 Pygame 在屏幕上绘制这个数组的条形图。接着,通过二分查找算法对有序数组进行查找,动画效果可视化每一步的变化。在查找的过程中,程序通过比较目标值和数组中间元素,逐步缩小搜索范围,高亮显…

使用 SDKMAN 管理多版本本地 Java 环境---Centos8 Windows

文章目录 windows 安装centos8 安装卸载sdkman使用 windows 安装 SDKMAN是一个 jdk 多版本管理工具,类似于 nodejs 中的 nvm。可以在本地存在多个 java 环境,快速切换功能,同时,他不止于 java sdk,还有maven、tomcat等…

如何安装RAD Studio 12(delphi 12)

如何安装RAD Studio 12(delphi 12) RAD Stuido 12 Athens How to install RAD Studio 12 29.0.50491.5718 InterBase 2020 14.5.0.864(x64) 14.5.0.864(x86) Download: http://altd.embarcadero.com/download/radstudio/12.0/RADStudio_12_0_49157…

血的教训---入侵redis并免密登录redis所在服务器漏洞复现

血的教训—入侵redis并免密登录redis所在服务器漏洞复现 今天就跟着我一起来入侵redis并免密登录redis所在服务器吧,废话不多说,我们直接开始吧。 这是一个体系的学习步骤,当然如果基础扎实的话可以继续往下面看 以下都是关联的文章&#xff…