温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣.

系列文章第一篇是拥抱大数据:凯哥带你从零学大数据系列-学习大数据前奏(必读)(点我)!

课程重点:

1 函数式接口函数式接口的概念函数式接口的判断@FunctionalInterface
2 lambda表达式的语法基础的语法语法的精简(参数、方法体)
3 函数引用静态、非静态、构造方法的引用对象方法的特殊引用

22.1. Lambda表达式的简介

22.1.1. Lambda表达式的概念

lambda表达式, 是Java8的一个新特性, 也是Java8中最值得学习的新特性之一。

lambda表达式, 从本质来讲, 是一个匿名函数。 可以使用使用这个匿名函数, 实现接口中的方法。 对接口进行非常简洁的实现, 从而简化代码。

22.1.2. Lambda表达式的使用场景

通常来讲, 使用lambda表达式, 是为了简化接口实现的。

关于接口实现, 可以有很多种方式来实现。 例如: 设计接口的实现类、 使用匿名内部类。 但是lambda表达式, 比这两种方式都简单。

/**

22.1.3. Lambda表达式对接口的要求

虽然说, lambda表达式可以在一定程度上简化接口的实现。 但是, 并不是所有的接口都可以使用lambda表达式来简洁实现的。

lambda表达式毕竟只是一个匿名方法。 当实现的接口中的方法过多或者多少的时候, lambda表达式都是不适用的。

lambda表达式,只能实现函数式接口

22.1.4. 函数式接口

22.1.4.1. 基础概念

如果说, 一个接口中, 要求实现类必须实现的抽象方法, 有且只有一个! 这样的接口, 就是函数式接口。

// 这个接口中, 有且只有一个方法, 是实现类必须实现的, 因此是一个函数式接口

思考题: 下面的两个接口是不是函数式接口?interface Test7 {String toString();
}interface Test8 {void test();default void test1() {}static void test2() {}String toString();
}

22.1.4.2. @FunctionalInterface

是一个注解, 用在接口之前, 判断这个接口是否是一个函数式接口。 如果是函数式接口, 没有任何问题。 如果不是函数式接口, 则会报错。 功能类似于 @Override。

@FunctionalInterface

22.1.4.3. 系统内置的若干函数式接口

22.2. Lambda表达式的语法

22.2.1. Lambda表达式的基础语法

lambda表达式, 其实本质来讲, 就是一个匿名函数。 因此在写lambda表达式的时候, 不需要关心方法名是什么。

实际上, 我们在写lambda表达式的时候, 也不需要关心返回值类型。

我们在写lambda表达式的时候, 只需要关注两部分内容即可: 参数列表方法体

lambda表达式的基础语法:

参数部分 : 方法的参数列表, 要求和实现的接口中的方法参数部分一致, 包括参数的数量和类型。

方法体部分 : 方法的实现部分, 如果接口中定义的方法有返回值, 则在实现的时候, 注意返回值的返回。

-> : 分隔参数部分和方法体部分。

/**

22.2.2. Lambda表达式的语法进阶

在上述代码中, 的确可以使用lambda表达式实现接口, 但是依然不够简洁, 有简化的空间。

22.2.2.1. 参数部分的精简

  • 参数的类型

    • 由于在接口的方法中,已经定义了每一个参数的类型是什么。 而且在使用lambda表达式实现接口的时候, 必须要保证参数的数量和类型需要和接口中的方法保持一致。 因此, 此时lambda表达式中的参数的类型可以省略不写。
    • 注意事项:
      • 如果需要省略参数的类型, 要保证: 要省略, 每一个参数的类型都必须省略不写。 绝对不能出现, 有的参数类型省略了, 有的参数类型没有省略。
// 多个参数、无返回值的方法实现NoneReturnMutipleParameter lambda1 = (a, b) -> {System.out.println("多个参数、无返回值方法的实现: 参数a是 " + a + ", 参数b是 " + b);};

  • 参数的小括号

    • 如果方法的参数列表中的参数数量 有且只有一个 ,此时,参数列表的小括号是可以省略不写的。
    • 注意事项:
      • 只有当参数的数量是一个的时候, 多了、少了都不能省略。
      • 省略掉小括号的同时, 必须要省略参数的类型。
// 有参、无返回值的方法实现
NoneReturnSingleParameter lambda2 = a -> {System.out.println("一个参数、无返回值方法的实现: 参数是 " + a);
};

22.2.2.2. 方法体部分的精简

  • 方法体大括号的精简

    • 当一个方法体中的逻辑, 有且只有一句的情况下, 大括号可以省略。
// 有参、无返回值的方法实现
NoneReturnSingleParameter lambda2 = a -> System.out.println("一个参数、无返回值方法的实现: 参数是 " + a);  

  • return的精简

    • 如果一个方法中唯一的一条语句是一个返回语句, 此时在省略掉大括号的同时, 也必须省略掉return。
SingleReturnMutipleParameter lambda3 = (a, b) -> a + b;

22.3. 函数引用

lambda表达式是为了简化接口的实现的。 在lambda表达式中, 不应该出现比较复杂的逻辑。 如果在lambda表达式中出现了过于复杂的逻辑, 会对程序的可读性造成非常大的影响。 如果在lambda表达式中需要处理的逻辑比较复杂, 一般情况会单独的写一个方法。 在lambda表达式中直接引用这个方法即可。

或者, 在有些情况下, 我们需要在lambda表达式中实现的逻辑, 在另外一个地方已经写好了。 此时我们就不需要再单独写一遍, 只需要直接引用这个已经存在的方法即可。

函数引用: 引用一个已经存在的方法, 使其替代lambda表达式完成接口的实现。

22.3.1. 静态方法的引用

  • 语法:

    • 类::静态方法
  • 注意事项:

    • 在引用的方法后面, 不要添加小括号。
    • 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的一致。
  • 示例:
/*** @Description*/
public class Syntax1 {// 静态方法的引用public static void main(String[] args) {// 实现一个多个参数的、一个返回值的接口// 对一个静态方法的引用// 类::静态方法SingleReturnMutipleParameter lambda1 = Calculator::calculate;System.out.println(lambda1.test(10, 20));}private static class Calculator {public static int calculate(int a, int b) {// 稍微复杂的逻辑:计算a和b的差值的绝对值if (a > b) {return a - b;}return b - a;}}
}

22.3.2. 非静态方法的引用

  • 语法:

    • 对象::非静态方法
  • 注意事项:

    • 在引用的方法后面, 不要添加小括号。
    • 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的一致。
  • 示例:
/*** @Description*/
public class Syntax2 {public static void main(String[] args) {// 对非静态方法的引用,需要使用对象来完成SingleReturnMutipleParameter lambda = new Calculator()::calculate;System.out.println(lambda.test(10, 30));}private static class Calculator {public int calculate(int a, int b) {return a > b ? a - b : b - a;}}
}

22.3.3. 构造方法的引用

  • 使用场景

如果某一个函数式接口中定义的方法, 仅仅是为了得到一个类的对象。 此时我们就可以使用构造方法的引用, 简化这个方法的实现。

  • 语法

类名::new

  • 注意事项

可以通过接口中的方法的参数, 区分引用不同的构造方法。

  • 示例
/*** @Description*/
public class Syntax3 {private static class Person {String name;int age;public Person() {System.out.println("一个Person对象被实例化了");}public Person(String name, int age) {System.out.println("一个Person对象被有参的实例化了");this.name = name;this.age = age;}}@FunctionalInterfaceprivate interface GetPerson {// 仅仅是希望获取到一个Person对象作为返回值Person test();}private interface GetPersonWithParameter {Person test(String name, int age);}public static void main(String[] args) {// lambda表达式实现接口GetPerson lambda = Person::new;     // 引用到Person类中的无参构造方法,获取到一个Person对象Person person = lambda.test();GetPersonWithParameter lambda2 = Person::new;  // 引用到Person类中的有参构造方法,获取到一个Person对象lambda2.test("xiaoming", 1);}
}

22.3.4. 对象方法的特殊引用

如果在使用lambda表达式,实现某些接口的时候。 lambda表达式中包含了某一个对象, 此时方法体中, 直接使用这个对象调用它的某一个方法就可以完成整体的逻辑。 其他的参数, 可以作为调用方法的参数。 此时, 可以对这种实现进行简化。

/**

22.4. Lambda表达式需要注意的问题

这里类似于局部内部类、匿名内部类,依然存在闭包的问题。

如果在lambda表达式中,使用到了局部变量,那么这个局部变量会被隐式的声明为 final。 是一个常量, 不能修改值。

22.5. Lambda表达式的实例

22.5.1. 线程的实例化

Thread 

22.5.2. 集合的常见方法

ArrayList

22.5.3. 集合的流式编程

ArrayList

java lambda表达式_凯哥带你从零学大数据系列之Java篇---第二十二章:Lambda表达式...相关推荐

  1. map根据value值排序_凯哥带你从零学大数据系列之Java篇---第十九章:集合(Map+Collections)...

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  2. ios 获取一个枚举的所有值_凯哥带你从零学大数据系列之Java篇---第十一章:枚举...

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  3. jdbc代码_凯哥带你从零学大数据系列之数据库篇---第三章:JDBC基础

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  4. 多层数组如何遍历_带你从零学大数据系列之Java篇---第五章:数组

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  5. 鸟哥的Linux私房菜(基础篇)- 第二十六章、Linux 核心编译与管理

    第二十六章.Linux核心编译与管理 最近升级日期:2009/09/18 我们说的 Linux 其实指的就是核心 (kernel) 而已.这个核心控制你主机的所有硬件并提供系统所有的功能,所以说,他重 ...

  6. 鸟哥的Linux私房菜(服务器)- 第二十二章、邮件服务器: Postfix

    第二十二章.邮件服务器: Postfix 最近更新日期:2011/08/10 在这个邮件服务器的架设中,我们首先谈论 Mail 与 DNS 的重要相关性,然后依序介绍 Mail Server 的相关名 ...

  7. 鸟哥的Linux私房菜(基础篇)- 第二十四章、 X Window 配置介绍

    第二十四章. X Window 配置介绍 最近升级日期:2009/08/07 在 Linux 上头的图形介面我们称之为 X Window System,简称为 X 或 X11 罗!为何称之为系统呢?这 ...

  8. 鸟哥的Linux私房菜(基础篇)- 第二十五章、 Linux 备份策略

    第二十五章. Linux备份策略 最近升级日期:2009/09/18 万一不幸你的 Linux 被黑客入侵了.或是你的 Linux 系统由於硬件关系 (不论是天灾还是人祸) 而挂掉了!这个时候,请问如 ...

  9. linux覆盖文件如何还原_大数据笔试真题集锦-——第十九章Linux面试题

    第十九章目录 第十九章 Linux 19.1 Linux中.如何调整文件最大打开数 修改linux的软硬件限制文件/etc/security/limits.conf. 在文件尾部添加如下代码: * s ...

最新文章

  1. echarts相关设置
  2. 2020年必学的 10 大算法
  3. 「APIO2018」选圆圈
  4. Android布局整合include界面控件 示例
  5. sudo: /etc/sudoers is world writable 错误解决方案
  6. tableau 实战练习数据源分享_小白入行数据分析师3年-工作内容复盘分享含代码(二)-数据库及Tableau篇介绍...
  7. Hexo 博客自定义一个不使用主题模板渲染的独立页面
  8. JAVA中String类以形参传递到函数里面,修改后外面引用不能获取到更改后的值
  9. Oracle备份与还原(exp和imp),导出导入
  10. NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
  11. PyTorch 中如何指定GPU
  12. Mac 技巧 | CAD 汉化后无法新建模板怎么办?
  13. VS2019详细安装教程
  14. 什么是数字证书?数字证书在哪办理?
  15. java两个日期相减_java将两个日期相减得到天数
  16. android+日文输入法,玩转手机日语输入法(安卓/iphone)
  17. c php embed,使用PHP Embed SAPI实现Opcodes查看器
  18. 给电脑C盘系统盘瘦身的四种方法
  19. arcengine java_浅析 ArcEngine Java - EngineViewer 例子
  20. JavaScript 专题之惰性函数

热门文章

  1. SAP CRM IBASE的archive方法
  2. SAP ABAP Netweaver里进程能够申请的最大内存
  3. ABAP面试题系列:写一组会出现死锁(Deadlock)的ABAP程序
  4. UI5_INFO_FETCH_FROM_DB
  5. why I cannot set SAP UI5 dropdown list as not selected
  6. WebIDE Initialization process
  7. how do you usually upload picture in SCN A workaround for current SCN upload is
  8. webdynpro view navigation - the same as Webclient UI
  9. sendData to ABAP backend via multiple form content type
  10. [SAP成都] SAP UI5应用的sap-ui-core.js被加载之前,还有哪些js文件被加载了