Lambda表达式

函数式编程思想概述

在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿什么东西做什么事情”。相对而言,面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做。
面向对象的思想:
​ 做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:
​ 只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程

冗余的Runnable代码

    创建Runnable接口的实现类,重写run方法,设置线程任务public class RunnableImpl implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" 新线程创建了");}
}
public static void main(String[] args) {//创建Runnable接口的实现类对象RunnableImpl run = new RunnableImpl();//创建Thread类对象,构造方法中传递Runnable接口的实现类Thread t = new Thread(run);//调用start方法开启新线程,执行run方法t.start();//简化代码,使用匿名内部类,实现多线程程序Runnable r = new Runnable(){@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" 新线程创建了");}};new Thread(r).start();//继续简化代码,直接传递匿名内部类new Thread(new Runnable(){@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" 新线程创建了");}}).start();}
}

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

Lambda表达式的标准格式:

由三部分组成:a.一些参数b.一个箭头c.一段代码

格式:

(参数列表) -> {一些重写方法的代码};

解释说明格式:

():接口中抽象方法的参数列表,没有参数,就空着;有参数就写出参数,多个参数使用逗号分隔
->:传递的意思,把参数传递给方法体{}
{}:重写接口的抽象方法的方法体

public static void main(String[] args) {//使用匿名内部类的方式,实现多线程new Thread(new Runnable(){@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" 新线程创建了");}}).start();//使用Lambda表达式,实现多线程new Thread(()->{   //()空括号中为空,其实就是run方法中的参数为空System.out.println(Thread.currentThread().getName()+" 新线程创建了");}).start();//优化省略Lambdanew Thread(()->System.out.println(Thread.currentThread().getName()+" 新线程创建了")).start();
}

用Lambda标准格式(无参无返回)

题目
给定一个厨子Cook接口,内含唯一的抽象方法makeFood,且无参数、无返回值。如下:

java public interface Cook { void makeFood(); }

在下面的代码中,请使用Lambda的标准格式调用invokeCook方法,打印输出“吃饭啦!”字样:

private static void invokeCook(Cook cook) {cook.makeFood();
}

代码实现:
定一个厨子Cook接口,内含唯一的抽象方法makeFood

public interface Cook {//定义无参数无返回值的方法makeFoodpublic abstract void makeFood();
}
需求:给定一个厨子Cook接口,内含唯一的抽象方法makeFood,且无参数、无返回值。使用Lambda的标准格式调用invokeCook方法,打印输出“吃饭啦!”字样public class Demo01Cook {public static void main(String[] args) {//调用invokeCook方法,参数是Cook接口,传递Cook接口的匿名内部类对象invokeCook(new Cook() {@Overridepublic void makeFood() {System.out.println("吃饭了");}});//现在使用Lambda表达式,简化匿名内部类的书写invokeCook(()->{//无参数,空括号System.out.println("吃饭了");});//优化省略LambdainvokeCook(()-> System.out.println("吃饭了"));}//定义一个方法,参数传递Cook接口,方法内部调用Cook接口中的方法makeFoodpublic static void invokeCook(Cook cook){cook.makeFood();}
}

Lambda的参数和返回值

需求: 使用数组存储多个Person对象 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
下面举例演示java.util.Comparator接口的使用场景代码,其中的抽象方法定义为:

public abstract int compare(T o1, T o2);

当需要对一个对象数组进行排序时,Arrays.sort方法需要一个Comparator接口实例来指定排序的规则。
假设有一个Person类,含有String name和int age两个成员变量:

 java public class Person { private String name; private int age;
// 省略构造器、toString方法与Getter Setter
}
 Lambda表达式有参数有返回值的练习需求:使用数组存储多个Person对象对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序*/
public class Demo01Arrays {public static void main(String[] args) {//使用数组存储多个Person对象Person[] arr = {new Person("张小敬",18),new Person("李必",20)};//对数组中的Person对象使用Arrays的sort方法通过年龄进行升序(前边-后边)排序Arrays.sort(arr, new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {return o1.getAge()-o2.getAge();}});//使用Lambda表达式,简化匿名内部类Arrays.sort(arr,(Person o1, Person o2)->{return o1.getAge()-o2.getAge();});//优化省略LambdaArrays.sort(arr,(o1, o2)->o1.getAge()-o2.getAge());//遍历数组for (Person p : arr) {System.out.println(p);}}
}

练习:使用Lambda标准格式(有参有返回) 自定义接口

给定一个计算器Calculator接口,内含抽象方法calc可以将两个int数字相加得到和值

public interface Calculator {//定义一个计算两个int整数和的方法并返回结果public abstract int calc(int a, int b);//有参数传入,需要实现类重写该方法
}
/*定义一个方法参数传递两个int类型的整数参数传递Calculator接口方法内部调用Calculator中的方法 calc计算两个整数的和*/
public static void invokeCalc(int a,int b,Calculator c){//参数有三个,其中一个是接口int sum = c.calc(a,b);System.out.println(sum);
}
public static void main(String[] args) {//调用invokeCalc方法,方法的参数是一个接口,可以使用匿名内部类invokeCalc(10, 20, new Calculator() {//new一个匿名内部类@Overridepublic int calc(int a, int b) {return a+b;}});//使用Lambda表达式简化匿名内部类的书写invokeCalc(120,130,(int a,int b)->{return a+b;});//优化省略LambdainvokeCalc(120,130,(a,b)-> a + b);
}

Lambda省略格式

可推导即可省略

    Lambda强调的是“做什么”而不是“怎么做”,所以凡是可以根据上下文推导得知的信息,都可以省略。例如上例还可以使用Lambda的省略写法:
  java public static void main(String[] args) { invokeCalc(120, 130, (a, b) -> a + b); }

省略规则

    在Lambda标准格式的基础上,使用省略写法的规则为:小括号内参数的类型可以省略;如果小括号内有且仅有一个参数,则小括号可以省略;如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。上述代码都写出了省略格式。

小结:
可以省略的内容:
1.(参数列表):括号中参数列表的数据类型,可以省略不写
2.(参数列表):括号中的参数如果只有一个,那么类型和()都可以省略
3.{一些代码}:如果{}中的代码只有一行,无论是否有返回值,都可以省略({},return,分号)
注意:要省略{},return,分号必须一起省略

public static void main(String[] args) {//JDK1.7版本之前,创建集合对象必须把前后的泛型都写上ArrayList<String> list01 = new ArrayList<String>();//JDK1.7版本之后,=号后边的泛型可以省略,后边的泛型可以根据前边的泛型推导出来ArrayList<String> list02 = new ArrayList<>();
}

Lambda的使用前提

Lambda的语法非常简洁,完全没有面向对象复杂的束缚。但是使用时有几个问题需要特别注意:

  1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。 无论是JDK内置的Runnable、Comparator接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda。
  2. 使用Lambda必须具有上下文推断。 也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
    备注:有且仅有一个抽象方法的接口,称为“函数式接口”。

进阶13 Lambda表达式相关推荐

  1. c#进阶之lambda表达式

    阅读之前,先确保对委托有基本的了解,传送门 c#进阶之浅析委托和事件. lambda表达式雏形第一步 在委托那篇文章,绑定的的方法都是具名函数,为了简化书写,可以换成匿名函数 public deleg ...

  2. Python学习(13)--Lambda表达式和switch语句的实现

    1.Lambda表达式定义匿名函数    在Python中,Lambda表达式是用来快速定义一个最小函数,这个函数小到什么程度呢,小到只有一行代码,一条语句,在Python中有时候我们为了提高程序的可 ...

  3. Java总结13 Lambda表达式 和 方法引用 的概念与应用

    一.Lambda表达式 一种代码简洁又抽象的表达方式,它能够在一个方法要调用某个接口的抽象方法前,对其要调用的抽象方法实现重写. 1.Lambda使用条件 1.必须要保证它是某个接口中唯一的一个抽象方 ...

  4. java lambda表达式详解_Java8新特性Lambda表达式详解

    课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...

  5. 【Java 进阶】匿名类(代码传递、回调、过滤器)、Lambda表达式(方法引用)、函数式接口(Supplier、Consumer、Predicate、Function)

    匿名类 匿名类(Anonymous Class) 匿名类的使用注意 匿名类 - 代码传递 - 测试代码运行时间的工具类 匿名类 - 回调 - 简易网络请求 匿名类 - 过滤器 - 获取目录下的所有文件 ...

  6. Java进阶(五十五)-Java Lambda表达式入门

    原文链接: Start Using Java Lambda Expressions 下载示例程序 Examples.zip . 简介   (译者注:虽然看着很先进,其实Lambda表达式的本质只是一个 ...

  7. 02java进阶03-异常、线程、同步、线程池、Lambda表达式、File类、递归

    目录 一.异常 二.异常的处理 三.自定义异常 四.多线程 五.线程.同步 5.1.线程 5.2同步 5.3线程安全 5.4线程状态 六.等待唤醒机制 6.1 线程间通信 6.2 等待唤醒机制 6.3 ...

  8. [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用

    [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是 ...

  9. java8 ie_Java8语法糖之Lambda表达式_Hudie.的博客-CSDN博客

    原文作者:编程一只蝶 原文标题:Java8语法糖之Lambda表达式 发布时间:2021-02-16 13:08:40 一.Lambda表达式简介 Lambda表达式,是Java8的一个新特性,也是J ...

最新文章

  1. array.array python yhzf
  2. python加颜色_Python 给屏幕打印信息加上颜色的实现方法
  3. Apache下PHP的几种工作方式
  4. 教你怎么在vi和vim上查找字符串
  5. .Net Core 微服务容器系列基础目录篇
  6. [PAT乙级]1010 一元多项式求导
  7. 给mac配置adb 路径
  8. oracle 11i 供应商api,Oracle EBS AP 供应商API
  9. Codeforces 2 A. Winner
  10. .NetCore下使用NPOI绘制统计图表
  11. 2021 年下半年软考-初级程序员考后感想
  12. 带通滤波器电路图设计(转)
  13. 数据库原理和应用(2)—— 数据库系统的组成
  14. 如何安装2018matlab,MATLAB 2018a软件安装教程
  15. MySQL数据库基础——强大的select之二,更加精彩的功能
  16. 下午到英东游泳馆游泳了
  17. 第世界上第一代电子计算机,第一代电子计算机
  18. 腾讯soso退出历史舞台,搜索结果全部由搜狗提供
  19. 哈工大软件构造Lab2
  20. 【纪中受难记】——Day10:逐渐自闭

热门文章

  1. tensorflow2.1学习--认识张量和常用函数二
  2. 微信公众号完美解决关注后三次获取media_id重复3次的问题
  3. 关于JavaScript中return的使用情况
  4. python迭代器和生成器_Python迭代器与生成器
  5. pl/mysql安装_MySQL安装
  6. iis web服务扩展_Web服务器系统都有哪些类型?都有什么优点呢?
  7. 前端开源项目周报0418
  8. GOF23设计模式之单例模式
  9. SQL NOTE--VIEW
  10. The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local Machine 完美解决