Lambda表达式详解

使用匿名内部类存在的问题

当需要启动一个线程去完成任务时,通常会通过 Runnable 接口来定义任务内容,并使用 Thread 类来启动该线程。
传统写法, 代码如下:
public class LambdaTest1 {public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("新线程任务执行啦!");}}).start();}
}
由于面向对象的语法要求,首先创建一个 Runnable 接口的匿名内部类对象来指定线程要执行的任务内容,再将其交 给一个线程来启动。
代码分析 :

对于 Runnable 的匿名内部类用法,可以分析出几点内容:

  • Thread类需要Runnable接口作为参数,其中的抽象 run 方法是用来指定线程任务内容的核心
  • 为了指定 run 的方法体,不得不需要 Runnable 接口的实现类
  • 为了省去定义一个 Runnable 实现类的麻烦,不得不使用匿名内部类
  • 必须覆盖重写抽象 run 方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错
  • 而实际上,似乎只有方法体才是关键所在

Lambda体验

Lambda 是一个 匿名函数 ,可以理解为一段可以传递的代码。  
Lambda 表达式写法, 代码如下:
借助Java 8 的全新语法,上述 Runnable 接口的匿名内部类写法可以通过更简单的 Lambda 表达式达到相同的效果
public class LambdaTest2 {public static void main(String[] args) {new Thread(() -> System.out.println("新线程任务执行!")).start(); // 启动线程}
}
这段代码和刚才的执行效果是完全一样的,可以在 JDK 8 或更高的编译级别下通过。从代码的语义中可以看出:我们 启动了一个线程,而线程任务的内容以一种更加简洁的形式被指定。
我们只需要将要执行的代码放到一个 Lambda 表达式中,不需要定义类,不需要创建对象

Lambda的优点

一句话总结:简化匿名内部类的使用,语法更加简单

Lambda的标准格式

Lambda 省去面向对象的条条框框, Lambda 的标准格式格式由 3 个部分 组成:
( 参数类型 参数名称 ) -> {
        代码体;
}
格式说明:
  • (参数类型 参数名称):参数列表
  • {代码体;}:方法体
  • -> :箭头,分隔参数列表和方法体
Lambda与方法的对比:
匿名内部类:
public void run() {System.out.println("aa");
}

Lambda:

() -> System.out.println("bb!")
无参数无返回值的Lambda:
interface Swimmable {public abstract void swimming();
}
package com.itheima.demo01lambda;
public class Demo02LambdaUse {public static void main(String[] args) {//调用匿名内部类的方法goSwimming(new Swimmable() {@Overridepublic void swimming() {System.out.println("匿名内部类游泳");}});//调用Lambda表达式来写goSwimming(() -> {System.out.println("Lambda游泳");});}//定义一个方法,参数传一个Swimmable接口public static void goSwimming(Swimmable s) {s.swimming();}
}

小结:以后我们看到方法的参数是接口就可以考虑使用Lambda表达式

我们可以这么认为:Lambda表达式就是对接口中的抽象方法的重写,但是接口必须是函数式接口,有且仅有一个抽象方法的接口。

有参数有返回值的Lambda:
下面举例演示 java.util.Comparator<T> 接口的使用场景代码,其中的抽象方法定义为:
  • public abstract int compare(T o1, T o2);
当需要对一个对象集合进行排序时, Collections.sort 方法需要一个 Comparator 接口实例来指定排序的规则。
传统写法
如果使用传统的代码对 ArrayList 集合进行排序,写法如下:
public class Person {private String name;private int age;private int height;// 省略其他
}
package com.itheima.demo01lambda;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
public class Demo03LambdaUse {public static void main(String[] args) {ArrayList<Person> persons = new ArrayList<>();persons.add(new Person("刘德华", 58, 174));persons.add(new Person("张学友", 58, 176));persons.add(new Person("刘德华", 54, 171));persons.add(new Person("黎明", 53, 178));Collections.sort(persons, new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {return o1.getAge() - o2.getAge();}});for (Person person : persons) {System.out.println(person);}}
}
这种做法在面向对象的思想中,似乎也是 理所当然 的。其中 Comparator 接口的实例(使用了匿名内部类)代表了“ 按照年龄从小到大 的排序规则。
Lambda 写法
package com.itheima.demo01lambda;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
public class Demo03LambdaUse {
public static void main(String[] args) {ArrayList<Person> persons = new ArrayList<>();persons.add(new Person("刘德华", 58, 174));persons.add(new Person("张学友", 58, 176));persons.add(new Person("刘德华", 54, 171));persons.add(new Person("黎明", 53, 178));Collections.sort(persons, (o1, o2) -> {return o1.getAge() - o2.getAge();});for (Person person : persons) {System.out.println(person);}System.out.println("-----------------");List<Integer> list = Arrays.asList(11, 22, 33, 44);list.forEach(new Consumer<Integer>() {@Overridepublic void accept(Integer integer) {System.out.println(integer);}});System.out.println("-----------------");list.forEach((s) -> {System.out.println(s);});}
}

Lambda省略格式

Lambda 标准格式的基础上,使用省略写法的规则为:
1. 小括号内参数的类型可以省略
2. 如果小括号内 有且仅有一个参数 ,则小括号可以省略
3. 如果大括号内 有且仅有一个语句 ,可以同时省略大括号、 return 关键字及语句分号
(int a) -> {return new Person();
}

省略后:

a -> new Person()

Lambda使用的前提条件

Lambda 的语法非常简洁,但是 Lambda 表达式不是随便使用的,使用时有几个条件要特别注意:
1. 方法的参数或局部变量类型必须为接口才能使用 Lambda
2. 接口中有且仅有一个抽象方法

函数式接口

函数式接口在 Java 中是指: 有且仅有一个抽象方法的接口
函数式接口,即适用于函数式编程场景的接口。而 Java 中的函数式编程体现就是 Lambda ,所以函数式接口就是可以
适用于 Lambda 使用的接口。只有确保接口中有且仅有一个抽象方法, Java 中的 Lambda 才能顺利地进行推导。
FunctionalInterface 注解
@Override 注解的作用类似, Java 8 中专门为函数式接口引入了一个新的注 @FunctionalInterface 。该注解可用于一个接口的定义上:
@FunctionalInterface
public interface Operator {void myMethod();
}
一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。不过,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。

Lambda和匿名内部类对比

1. 所需的类型不一样

  • 匿名内部类,需要的类型可以是类,抽象类,接口
  • Lambda表达式,需要的类型必须是接口

2. 抽象方法的数量不一样

  • 匿名内部类所需的接口中抽象方法的数量随意
  • Lambda表达式所需的接口只能有一个抽象方法

3. 实现原理不同

  • 匿名内部类是在编译后会形成class
  • Lambda表达式是在程序运行的时候动态生成class
当接口中只有一个抽象方法时,建议使用Lambda表达式,其他其他情况还是需要使用匿名内部类

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

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

相关文章

免费申请 HTTPS 证书的八大方法

大家好,我是CodeQi! 一位热衷于技术分享的码仔。 为了保证网站的安全和数据的隐私性,使用 HTTPS 加密协议已成为必需。HTTPS 证书由受信任的证书颁发机构 (CA) 签发,可以加密客户端和服务器之间的通信。 幸运的是,有许多方法可以免费申请 HTTPS 证书。本文将介绍八种方法…

Debezium系列之:记录一次数据库某张表部分数据未同步到hive表的原因

Debezium系列之:记录一次数据库某张表部分数据未同步到hive表的原因 一、背景二、查找数据丢失流程三、数据丢失原因四、解决方法一、背景 反馈mysql数据库中某张表的数据没有同步到hive中,现在需要排查定位下原因数据丢失一般常见需求排查的方向: 数据是否采集到hdfs上采集…

HTML+CSS笔记

标签 HTML标签 网页的大包围 整体网页内容的外衣 所有的网页文档内容都要写在 html标签内 lang属性&#xff0c;是指内容语言的&#xff0c;目的是让浏览器知晓这个页面的主要展示语言 是什么 只跟浏览器的翻译有关 主要展示的语言如果是英语 en&#xff0c;主要展示的语言如果…

Apache NiFi: 数据采集工具详解

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 欢迎关注微信公众号&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&a…

ubuntu 安装说明

最近准备学习Linux&#xff0c;所以下载了最新的ubuntu server版本24.04&#xff0c;将安装步骤记录下来供参考。 1.安装 挂载光驱和iso文件&#xff0c;启动虚拟机。启动后&#xff0c;你会看到 GRUB 菜单上有两个选项&#xff1a; Try or Install Ubuntu Server 和 Test mem…

电脑怎么录屏?3个超简单的方法,你一定要学会

在数字化时代&#xff0c;电脑录屏早已不再是一个新鲜词汇&#xff0c;看到他人分享的精彩录屏视频&#xff0c;您是否也想自己制作一些精彩视频出来供自己欣赏或分享给他人。那么&#xff0c;电脑怎么录屏&#xff1f;如何让电脑录屏变得更加前沿、有趣和高效呢&#xff1f;今…

使用PowerShell开启防火墙端口

使用PowerShell开启防火墙端口 引言 防火墙是网络安全的重要组成部分&#xff0c;它通过控制进出网络的流量来保护计算机和网络免受未经授权的访问。有时候&#xff0c;我们需要打开特定的防火墙端口以允许特定应用程序或服务的通信。本文将详细讲解如何使用 PowerShell 开启…

WPF UI InkCanvas 导师演示画板 演示 笔记 画笔 识别

<Grid><InkCanvas Name"inkCanvas"/><Button Content"识别" Click"Button_Click" VerticalAlignment"Bottom"/></Grid> 引用内库 Ink ink new Ink(); private void Button_Click(object sender, RoutedEvent…

13-错误-ERROR: duplicate key value violates unique constraint “ux_xxx“

13-错误-ERROR: duplicate key value violates unique constraint “ux_xxx” 更多内容欢迎关注我&#xff08;持续更新中&#xff0c;欢迎Star✨&#xff09; Github&#xff1a;CodeZeng1998/Java-Developer-Work-Note 技术公众号&#xff1a;CodeZeng1998&#xff08;纯纯…

从零到一:eBay自养号测评全流程解析与实操建议

eBay自养号测评是一种通过模拟真实买家行为&#xff0c;为卖家提供市场反馈并提升店铺权重和排名的技术手段。以下是进行eBay自养号测评的具体步骤和注意事项&#xff1a; 一、准备阶段 1. 技术配置&#xff1a;搭建境外服务器&#xff1a;选择稳定的境外服务器&#xff0c;模…

TPS54331 带载输出电压不稳定

TPS54331 带载输出电压不稳定 一、问题概述 TPS54331电源芯片&#xff0c;搭建DC12V转DC5V供电回路。TPS54331芯片外围电路是按照官网给的原理图搭建的&#xff0c;如下图1所示&#xff0c;但是在外围电路器件的布局上没有按照官网器件位置布局&#xff0c;如下图2所示&#x…

七月开刷|50天吃透660+880‼️

现在只刷一本题集根本不够 去做做24年的考研真题卷就什么都明白了&#xff0c;24年的卷子就是典型的知识点多&#xff0c;杂&#xff0c;计算量大。 而现在市面上的任何一本题集&#xff0c;都无法做到包含所有的知识点&#xff0c;毕竟版面有限&#xff01; 所以&#xff0…

vue ref怎么实现基本数据类型和复杂数据类型响应式

在Vue中&#xff0c;ref用于创建响应式的数据引用。对于基本数据类型&#xff08;如字符串、数字等&#xff09;&#xff0c;ref可以直接实现响应式。而对于复杂数据类型&#xff08;如对象或数组&#xff09;&#xff0c;需要使用reactive来创建响应式对象。 以下是如何使用re…

【教学类-55-07】20240705图层顺序挑战2*2、3*3、4*4(优化版)

背景需求: 今天有小红书上有一位客户定了“2*2、3*3、4*4”的图层挑战。 我打开原来写代码 【教学类-55-06】20240517图层顺序挑战(二格长条纸加黑色边框、2*2、3张,不重复12张,4坐标点颜色哈希值去重、保留3色)-CSDN博客文章浏览阅读1k次,点赞41次,收藏18次。【教学类…

Android zygote访谈录

戳蓝字“牛晓伟”关注我哦&#xff01; 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章&#xff0c;技术文章也可以有温度。 本文摘要 本文以访谈的方式来带大家了解zygote进程&#xff0c;了解zygote进程是啥&#xff1f;它的作用是啥&#xff1f;它是如何一步…

ECOLOGY权限调整转移过程中关闭执行页面导致权限转移失败解决方案

背景&#xff1a;在“OA后端应用中心/组织权限中心/权限管理/权限调整”中对“XXX”进行权限转移操作&#xff0c;权限转移数据达一万余条&#xff0c;因长时间没有转移完成&#xff0c;所以关了执行的页面。结果为XXX的权限没有转移走&#xff0c;再次进入尝试转移报警“服务器…

Unity3D中使用并行的Job完成筛选类任务详解

在Unity3D开发中&#xff0c;处理大量数据或执行复杂计算时&#xff0c;性能往往成为制约因素。为了提升游戏或应用的性能&#xff0c;Unity提供了强大的Job System&#xff0c;它允许开发者利用多线程和并行计算来优化数据处理过程。本文将详细介绍如何在Unity中使用并行的Job…

Java中的持续集成与持续部署(CI/CD)

Java中的持续集成与持续部署&#xff08;CI/CD&#xff09; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨Java中的持续集成&#xff08;Co…

富格林:曝光可信策略制止亏损

富格林指出&#xff0c;相信大家都对黄金投资的价值空间有目共睹&#xff0c;现如今黄金市场波动频繁&#xff0c;因此不少投资者也开始加入该市场试图赢得额外的财富。但作为新手投资者贸贸然地进场操作&#xff0c;亏损的几率是很大的&#xff0c;因此要学会掌握正规平台曝光…

什么是声明式编程?发展趋势怎么样的?

一、什么是声明式编程&#xff1f; 声明式编程&#xff08;Declarative programming&#xff09;是一种编程范式&#xff0c;与命令式编程相对立。它主要描述目标的性质&#xff0c;让计算机明白目标&#xff0c;而非具体的执行流程。在声明式编程中&#xff0c;开发者只需声明…