一、Lambda表达式

(1)函数式编程思想概述

  • 在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作”
  • 面向对象思想强调“必须通过对象的形式来做事情”
  • 函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做
    而我们要学习的Lambda表达式就是函数式思想的体现

(2)体验Lambda表达式

  • 需求:启动一个线程,在控制台输出一句话:多线程程序启动了

1. 方式1:定义一个类MyRunnable实现Runnable接口,重写run()方法

//创建MyRunnable类的对象
class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("多线程程序启动了...");}
}public class LambdaDemo {public static void main(String[] args) {//实现类的方式实现需求MyRunnable my = new MyRunnable();//创建Thread类的对象,把MyRunnable的对象作为构造参数传递Thread t = new Thread(my);//启动线程t.start();}
}

2. 方式2:匿名内部类的方式改进

public class LambdaDemo {public static void main(String[] args) {//匿名内部类的方式改进new Thread(new Runnable() {@Overridepublic void run() {System.out.println("多线程程序启动了...");}}).start();}
}
  • 匿名内部类中重写run()方法的代码分析
    ①、方法形式参数为空,说明调用方法时不需要传递参数
    ②、方法返回值类型为void,说明方法执行没有结果返回
    ③、方法体中的内容,是我们具体要做的事情

3. 方式3:Lambda表达式的方式改进

public class LambdaDemo {public static void main(String[] args) {//Lambda表达式改进new Thread(() -> {System.out.println("多线程程序启动了...");}).start();}
}
  • Lambda表达式的代码分析
    ①、():里面没有内容,可以看成是方法形式参数为空
    ②、->:用箭头指向后面要做的事情
    ③、{ }:包含一段代码,我们称之为代码块,可以看成是方法体中的内容

4. 三种方式实现需求的优缺点

  • 综合上述三个方法可以看出,当我们使用实现类的方式实现需求的时候,我们可以看到我们需要先创建一个实体类,然后将实现类的对象传进去才可以使用。
  • 当我们使用你们匿名内部类的方法实现需求时,我们可以发现需要重写run方法(当我们调用其他方法,忘记去重写什么方法时会比较懵逼),相比较也是比较麻烦的。
  • 当我们使用Lambda表达式来实现需求时,我们可以看到我们不用关心创建了什么实体类、重写了什么方法。我们只需要关心它最终要做的事情是System.out.println("多线程程序启动了...");

(3)Lambda表达式的标准格式

  • 组成Lambda表达式的三要素:形式参数,箭头,代码块
  • Lambda表达式的格式
    ①、格式:(形式参数) -> {代码块}
    ②、形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
    ③、->:由英文中画线和大于符号组成,固定写法。代表指向动作
    ④、代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

(四)Lambda表达式的练习

  • Lambda表达式的使用前提
    ①、有一个接口
    ②、接口中有且仅有一个抽象方法

练习1(抽象方法无参无返回值):

  • 定义一个接口(Eatable),里面定义一个抽象方法:void eat();
public interface Eatable {void eat();
}
  • 定义一个测试类(EatableDemo),在测试类中提供两个方法
    ①、一个方法是:useEatable(Eatable e)
    ②、一个方法是主方法,在主方法中调用useEatable方法

(1)通过实现类方法

class EatableImpl implements Eatable{@Overridepublic void eat() {System.out.println("一天一苹果,医生远离我");}
}public class EatableDemo {public static void main(String[] args) {//在主方法中调用useEatable方法Eatable e = new EatableImpl();useEatable(e);}private static void useEatable(Eatable e){e.eat();}
}

(2)匿名内部类的方式改进

public class EatableDemo {public static void main(String[] args) {//匿名内部类useEatable(new Eatable() {@Overridepublic void eat() {System.out.println("一天一苹果,医生远离我");}});}private static void useEatable(Eatable e){e.eat();}
}

(3)Lambda表达式的方式改进

public class EatableDemo {public static void main(String[] args) {//用Lambda表达式useEatable(() -> {System.out.println("一天一苹果,医生远离我");});}private static void useEatable(Eatable e){e.eat();}
}

练习2(抽象方法带参无返回值):

  • 定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);
public interface Flyable{void fly(String s);
}
  • 定义一个测试类(FlyableDemo),在测试类中提供两个方法
    ①、一个方法是:useFlyable(Flyable f)
    ②、一个方法是主方法,在主方法中调用useFlyable方法

(1)匿名内部类的方式

public class FlyableDemo {public static void main(String[] args) {//在主方法中调用useFlyable方法//匿名内部类useFlyable(new Flyable() {@Overridepublic void fly(String s) {System.out.println(s);System.out.println("飞机自驾游");}});}private static void useFlyable(Flyable f){f.fly("风和日丽,晴空万里");}
}

(2)Lambda表达式的方式改进

public class FlyableDemo {public static void main(String[] args) {//LambdauseFlyable((String s)-> {System.out.println(s);System.out.println("飞机自驾游");});}private static void useFlyable(Flyable f){f.fly("风和日丽,晴空万里");}
}

练习3(抽象方法带参有返回值):

  • 定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);
public interface Addable {int add(int x,int y);
}
  • 定义一个测试类(AddableDemo),在测试类中提供两个方法
    ①、一个方法是:useAddable(Addable a)
    ②、一个方法是主方法,在主方法中调用useAddable方法
public class AddableDemo {public static void main(String[] args) {//在主方法中调用useAddle方法//LambdauseAddable((int a, int b) -> {return a+b;});}private static void useAddable(Addable a){int sum = a.add(10,20);System.out.println(sum);}
}

(五)、Lambda表达式的省略模式

  • 省略规则:
    ①、参数类型可以省略。但是有多个参数的情况下,不能只省略一个
    ②、如果参数有且仅有一个,那么小括号可以省略
    ③、如果代码块的语句只有一条,可以省略大括号和分号,甚至是return
  • 定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);
public interface Flyable{void fly(String s);
}
  • 定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);
public interface Addable {int add(int x,int y);
}
/*Lambda表达式的省略模式*/
public class LambdaDemo {public static void main(String[] args) {//useAddable((int x,int y) -> {//    return x+y;//});//1.参数的类型可以省略,但是有多个参数的情况下,不能只省略一个useAddable((x,y) -> {return x+y;});//useFlyable((String s) ->{//    System.out.println(s);//});//2.如果参数有且只有一个,那么小括号可以省略useFlyable( s->{System.out.println(s);});//3.如果代码块的语句只有一条,可以省略大括号和分号useFlyable(s -> System.out.println(s));//4.如果代码块的语句只有一条,可以省略大括号和分号;如果有return,return也要省略useAddable((x,y) -> x+y );}private static void useFlyable(Flyable f){f.fly("风和日丽,晴空万里");}private static void useAddable(Addable a){int sum = a.add(10,20);System.out.println(sum);}
}

(六)Lambda表达式的注意事项

  • 注意事项:
    ①、使用Lambda必须要有接口,并且要求接口中有且仅有一个抽象方法
    ②、必须有上下文环境,才能推导出Lambda对应的接口
    ③、根据局部变量的赋值得知Lambda对应的接口:Runnable r = () -> System.out.println(“Lambda表达式”);
    ④、根据调用方法的参数得知Lambda对应的接口:new Thread(() -> System.out.println(“Lambda表达式”)).start();
/*Lambda表达式的注意事项*/
public class LambdaDemo {public static void main(String[] args) {//使用Lambda表达式必须要有接口,并且要求接口中有且仅有一个抽相方法useInter(()->System.out.println("好好学习,天天向上"));//必须有上下文环境,才能推导出Lambda对应的接口Runnable r = () -> System.out.println("Lambda表达式");new Thread(r).start();new Thread(() -> System.out.println("Lambda表达式")).start();}private static void useInter(Inter i){i.show();}
}

(七)Lambda表达式和匿名内部类的区别

  • 所需类型不同
    ①、匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
    ②、Lambda表达式:只能是接口
abstract class Animal {public abstract void method();
}
class Student {public void study(){System.out.println("爱生活,爱java");}
}public class LambdaDemo{public static void main(String[] args) {/*//匿名内部类useInter(new Inter() {@Overridepublic void show() {System.out.println("接口");}});useAnimal(new Animal() {@Overridepublic void method() {System.out.println("抽象类");}});useStudent(new Student(){@Overridepublic void study(){System.out.println("具体类");}});*///LambdauseInter(() -> System.out.println("接口"));//useAnimal(() -> System.out.println("抽象类"));//不可以//useStudent(() -> System.out.println("具体类"));//不可以}private static void useStudent(Student s){s.study();}private static void useAnimal(Animal a){a.method();}private static void useInter(Inter i){i.show();}
}
  • 使用限制不同
    ①、如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
    ②、如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
public interface Inter{void show();void show1();
}
public class LambdaDemo{public static void main(String[] args) {useInter(new Inter() {@Overridepublic void show() {System.out.println("show");//												

让你秒懂的Lambda表达式超级详细讲解相关推荐

  1. java8新特性之lambda表达式--超级详细版本

    java8新特性之lambda表达式 1.什么是lambda表达式?为什么用它? 2. 为什么Java需要lambda表达式? 3. lambda表达式的语法 4.函数式接口 4.1 什么是函数式接口 ...

  2. Lambda表达式超详细总结

    文章目录 1. 什么是Lambda表达式 2. 为什么使用Lambda表达式 3. Lambda表达式语法 4. 函数式接口 4.1 什么是函数式接口 4.2 自定义函数式接口 4.3 Java内置函 ...

  3. EL表达式 (超级详细!!)

    EL表达式 1.EL表达式的语法 EL(expression language)是为了让JSP写起来更加方便,他提供了在jsp中简化表达式的方法,让jsp的代码更加简化 语法结构:${expressi ...

  4. lambda函数的详细讲解

    本文转载自https://blog.csdn.net/zjuxsl/article/details/79437563,侵删 lambda是Python编程语言中使用频率较高的一个关键字.那么,什么是l ...

  5. openlaw爬虫超级详细讲解

    openlaw爬虫 openlaw网站有严格加密,代码可以运行,但是如果想获取太多数据建议根据官网要求来 1.openlaw内容页超链接加密 打开openlaw网站搜索刑事,打开检查,看见超链接是加密 ...

  6. 看这里看这里:结构体的超级详细讲解

    结构体 结构体在C语言中识非常重要的知识,想要学好C语言就必须学好结构体,那么什么是结构体呢?结构体是一些值的集合,这些值称为成员变量,而结构体的每个成员可以是不同类型的变量: 一.结构体的声明: 1 ...

  7. A*算法(超级详细讲解,附有举例的详细手写步骤)

    背景:项目需要接触此算法,以下是一些自学成果,如有不足之处,欢迎指出,必虚心接受.做了一份PPT来汇报,此处直接使用自己PPT的截图.部分图片来源网络,如有侵权立马删除,以下博文仅作为学习笔记.后期又 ...

  8. 防抖和截流超级详细讲解,易懂

    防抖函数:  在规定时间内只执行最后一次 代码解析: // 1.定义一个业务处理函数 function search() {console.log('业务处理函数执行,执行搜索', Math.rand ...

  9. 宽度优先搜索算法(BFS)详解(超级详细讲解,附有大图)

    目录 一.宽度优先搜索(BFS)是什么? 二.图解宽搜(BFS) 三.对比与发现 四.工具--队列 五.模板 六.最后 一.宽度优先搜索(BFS)是什么? 百度百科这样说: 宽度优先搜索算法(又称广度 ...

最新文章

  1. Verilog 流水线加法器
  2. linux 时钟同步 chrony 简介
  3. 8_Markdown和LaTex的使用中的一些小技巧
  4. 在ASP.NET AJAX 1.0框架中访问Web服务
  5. java传送字符到前端_mina实现服务器与客户端传送对象或字符串
  6. linux最初配置( vimrc设置 、tab键设置 inputrc、中文输入法等等)
  7. java加载properties文件的几种方式,java高级面试笔试题
  8. java一次性查询几十万,几百万数据解决办法
  9. 【net core】VSCode调试NetCore Web项目问题集锦
  10. java购物系统需求分析_java网上购物系统需求分析.doc
  11. 一般线性模型和混合线性模型_从零开始的线性混合模型
  12. 异步fifo_【好设计论文】一种面向异步FIFO的低开销容错机制研究
  13. 2021-07-29 vue事件冒泡和事件捕获,阻止冒泡和阻止浏览器默认行为
  14. python—简单的数据抓取一(简单的文字数据抓取(认识cookie)、简单的图片抓取)
  15. 德州达拉斯大学计算机录取要求,德克萨斯大学达拉斯分校申请条件(德克萨斯大...
  16. DS 500PM mobil便携式智能图表记录仪订购代码0500 5340_A1_B1_C1_D1_E1
  17. 当前年的日历存储到数据库,用于判断某一天是假期还是工作日
  18. 单片机51 流水灯基本程序
  19. word行首空格下划线_在Word文档行首空格和下划线问题的解决
  20. 单片机ADC采样算法----有效值采样法

热门文章

  1. 初学入门YOLOv5手势识别之制作并训练自己的数据集
  2. 深入浅出CChart 每日一课——第五课 回到折线图,苦逼屌丝之万丈高楼平地起
  3. ES6——Symbol属性与for...of循环迭代器
  4. 深度学习可解释性研究(二): Understanding Black-box Predictions via Influence Functions(详细公式推导)
  5. 系统分析师电子版_3个月,我从待业青年变成数据分析师,月薪15000!
  6. pmc订单表格_PMC生产计划表
  7. 《CSAPP》(第3版)答案(第三章)(一)
  8. ipset如何与netfilter内核模块进行通信
  9. ECMAScript(pink)
  10. shell脚本——sql连接及其查询结果重定向到txt