Lambda 表达式也称为闭包,是匿名类的简短形式。Lambda 表达式简化了【单一抽象方法声明接口】的使用,因此 lambda 表达式也称为功能接口。
在 Java SE 7 中,单一方法接口可使用下列选项之一实现。
  • 创建接口实现类。
  • 创建匿名类。

可以使用 lambda 表达式实现功能接口,无需创建类或匿名类。Lambda 表达式只能用于单一方法声明接口。

Lambda 表达式旨在支持多核处理器架构,这种架构依赖于提供并行机制的软件,而该机制可以提高性能、减少完成时间。

Lambda 表达式具有以下优点:

  • 简明的语法
  • 方法引用和构造函数引用
  • 相比于匿名类,减少了运行时开销

Lambda 表达式的语法

Lambda 表达式的语法如下所示。

(formal parameter list) ->{ expression or statements }

参数列表是一个逗号分隔的形式参数列表,这些参数与功能接口中单一方法的形式参数相对应。指定参数类型是可选项;如果未指定参数类型,将从上下文推断。

参数列表必须用括号括起来,但当指定的单一参数不带参数类型时除外,指定单一形式参数时可以不带括号。如果功能接口方法不指定任何形式参数,则必须指定空括号。

参数列表后面是 -> 运算符,然后是 lambda 主体,即单一表达式或语句块。Lambda 主体的结果必须是下列值之一:

  • void,如果功能接口方法的结果是 void
  • Java 类型、基元类型或引用类型,与功能接口方法的返回类型相同

Lambda 主体根据以下选项之一返回结果:

  • 如果 lambda 主体是单一表达式,则返回表达式的值。
  • 如果该方法具有返回类型,且 lambda 主体不是单一表达式,则 lambda 主体必须使用 return 语句返回值。
  • 如果功能接口方法的结果是 void,可以提供一个 return 语句,但这不是必需的。

语句块必须包含在大括号内,除非语句块是一个方法调用语句,而其调用的方法的结果是 void。Lambda 主体的结果必须与功能接口中单一方法的结果相同。

例如,如果功能接口方法的结果是 void,则 lambda 表达式主体不能返回值。如果功能接口方法具有返回类型String,则 lambda 表达式主体必须返回 String。如果 lambda 主体是一条语句,并且该方法具有一个返回类型,则该语句必须是return 语句。调用 lambda 表达式时,将运行 lambda 主体中的代码。

功能接口

Lambda 表达式与功能接口一起使用,功能接口实际上是一种只有一个抽象方法的接口;功能接口可以包含一个同时也存在于 Object 类中的方法。功能接口的示例有 java.util.concurrent.Callable(具有单一方法 call())和 java.lang.Runnable(具有单一方法run())。

区别在于,匿名接口类需要指定一个实例创建表达式,以便接口和编译器用来创建接口实现类的实例。与指定接口类型(或类类型)的匿名类不同,lambda 表达式不指定接口类型。从上下文推断为其调用 lambda 表达式的功能接口,也称为 lambda 表达式的目标类型。

Lambda 表达式的目标类型

Lambda 表达式有一个隐式的目标类型与之关联,因为未明确指定接口类型。在 lambda 表达式中,lambda 转换的目标类型必须是一个功能接口。从上下文推断目标类型。因此,lambda 表达式只能用在可以推断目标类型的上下文中。此类上下文包括

  • 变量声明
  • 赋值
  • return 语句
  • 数组初始值设定项
  • 方法或构造函数的参数
  • Lambda 表达式主体
  • 三元条件表达式
  • 转换表达式

在 Eclipse IDE 中使用 Lambda 表达式

前提条件
  • 1、安装了 JDK 8 的 JRE
  • 2、所使用的 Eclipse 要支持 Java8 的编译
在 Eclipse 中,选择 Windows > Preferences > Java > Installed JREs,勾选JDK 8 的 JRE
选择 Windows > Preferences > Java >Compiler,然后将 Compiler compliance level 设为 1.8。如果没有1.8的选项,说明此eclipse版本不支持。

单击 Apply,然后单击 OK。

Eclipse Luna  SR2已经添加了对Java8的支持,可直接到官网下载

在 AndroidStudio 中使用 Lambda 表达式

Gradle(Project)中添加classpath【classpath 'me.tatarka:gradle-retrolambda:3.2.0'】

Gradle(Module)中添加apply【apply plugin: 'me.tatarka.retrolambda'】

Gradle(Module)中添加compileOptions
  1. compileOptions {
  2. targetCompatibility 1.8
  3. sourceCompatibility 1.8
  4. }

JDK版本选择1.8

用 Lambda 表达式创建 Hello 应用程序

我们都很熟悉 Hello 应用程序,当我们提供一个姓名时,它会输出一条消息。Hello 类声明了两个字段、两个构造函数和一个 hello()方法来输出消息,如下所示。

  1. public class Hello {
  2. String firstname;
  3. String lastname;
  4. public Hello() {
  5. }
  6. public Hello(String firstname, String lastname) {
  7. this.firstname = firstname;
  8. this.lastname = lastname;
  9. }
  10. public void hello() {
  11. System.out.println("Hello " + firstname + " " + lastname);
  12. }
  13. public static void main(String[] args) {
  14. Hello hello = new Hello(args[0], args[1]);
  15. hello.hello();
  16. }
  17. }
现在,我们来看看 lambda 表达式如何简化 Hello 示例中的语法。
首先,我们需要创建一个功能接口,该接口包含一个返回“Hello”消息的方法。
  1. interface HelloService {
  2. String hello(String firstname, String lastname);
  3. }
创建一个 lambda 表达式,它包含两个参数,与接口方法的参数相匹配。在 lambda 表达式的主体中,使用 return 语句创建并返回根据firstname 和 lastname 构造的“Hello”消息。返回值的类型必须与接口方法的返回类型相同,并且 lambda 表达式的目标必须是功能接口HelloService。
  1. public class Test {
  2. public static void main(String[] args) {
  3. HelloService helloService = (String firstname, String lastname) -> {
  4. return "Hello " + firstname + " " + lastname;
  5. };
  6. System.out.println(helloService.hello("包青天", "白乾涛"));
  7. }
  8. }

Lambda 表达式中的局部变量

  • Lambda 表达式不会定义新的作用域,lambda 表达式的作用域与封闭作用域相同。如果 Lambda 主体声明的局部变量与封闭作用域内的变量重名,将产生编译器错误 Lambda expression's local variable i cannot re-declare another local variable defined in an enclosing scope
  • 局部变量无论是在 lambda 表达式主体中声明,还是在封闭作用域中声明,使用之前都必须先初始化,否则将产生编译器错误 The local variable i may not have been initialized
  • lambda 表达式中使用的变量必须处于终态或等效终态,否则将产生编译器错误 Variable i is required to be final or effectively final
  • Lambda 主体中的 this 和 super 引用与封闭上下文中一样,因为 lambda 表达式不会引入新的作用域,这与匿名类不同。

Lambda 表达式是一种匿名方法

Lambda 表达式实际上是一种匿名方法实现;指定形式参数,并使用 return 语句返回值。匿名方法必须按照以下规则所规定的与其实现的功能接口方法兼容。

  • Lambda 表达式返回的结果必须与功能接口方法的结果兼容。返回值的类型可以是功能接口方法声明中返回类型的子类型。
  • Lambda 表达式签名必须与功能接口方法的签名相同。
  • Lambda 表达式只能抛出那些在功能接口方法的 throws 子句中声明了异常类型或异常超类型的异常。

Lambda 表达式是一种多态表达式

Lambda 表达式的类型是从目标类型推导出来的类型。相同的 lambda 表达式在不同的上下文中可以有不同的类型。此类表达式称为多态表达式。

不支持泛型 Lambda。Lambda 表达式不能引入类型变量。

Lambda表达式 简介 语法 示例的更多相关文章

  1. Lambda表达式 简介 语法 示例 匿名内部类

    在AS中使用 Lambda 表达式 Demo地址:https://github.com/baiqiantao/MultiTypeTest.git Gradle(Project级别)中添加classpa ...

  2. Java 8特性探究(1):通往lambda之路与 lambda表达式10个示例

    本文由 ImportNew 函数式接口 函数式接口(functional interface 也叫功能性接口,其实是同一个东西).简单来说,函数式接口是只包含一个方法的接口.比如Java标准库中的ja ...

  3. Java 8 Lambda表达式10个示例【存】

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

  4. java8 快速入门 lambda表达式 Java8 lambda表达式10个示例

    本文由 ImportNew - lemeilleur 翻译自 javarevisited.欢迎加入翻译小组.转载请见文末要求. Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发 ...

  5. Java8 lambda表达式10个示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...

  6. Lambda表达式常用代码示例

    Lambda表达式常用代码示例 2017-10-24 目录 1 Lambda表达式是什么2 Lambda表达式语法3 函数式接口是什么  3.1 常用函数式接口4 Lambdas和Streams结合使 ...

  7. Java8的Lambda表达式简介

    先阐述一下JSR(Java Specification Requests)规范,即Java语言的规范提案.是向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求 ...

  8. Java8 lambda表达式10个示例<转>

    例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...

  9. 【Java8新特性】Lambda表达式基础语法,都在这儿了!!

    写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...

随机推荐

  1. python自动开发之第十八天

    一.JS正则 test - 判断字符串是否符合规定的正则 rep = /\d+/; rep.test("asdfoiklfasdf89asdfasdf") # true rep = ...

  2. 关于system(”pause“);的作用和意义

    注意:不要再return 的语句之后加,那样就执行不到了. system() 是调用系统命令:pause 暂停命令: 如果加有  system(”pause“): 这样在运行到此处时,会显示“Pres ...

  3. 工作总结:VS2010/MFC编程入门之十六(对话框:消息对话框)

    原文地址:http://www.jizhuomi.com/software/171.html 我们在使用Windows系统的过程中经常会见到消息对话框,提示我们有异常发生或提出询问等.因为在软件开发中 ...

  4. SharePoint2013 Powershell script to get site Title, Site Owner, Site user count and usage

    Powershell script to get site Title, Site Owner, Site user count and usage Add-PSSnapin microsoft.sh ...

  5. 利用低成本的MCU的UART驱动智能卡

    在银行.身份识别和电信市场中,对安全和增强的功能性不断增长的需要,增加了全球范围智能卡的使用.另一方面,这也使得对安全性较低的磁条卡的使用量下降. 然而,所需的基于智能卡系统中,适当的通信系统的硬件和 ...

  6. 电容式触摸控制器PCB布局

    在目前市场上可提供的PCB(印刷电路板)基材中,FR4是最常用的一种.FR4是一种玻璃纤维增强型环氧树脂层压板,PCB可以是单层或多层. 在触摸模块的尺寸受限的情况下,使用单层PCB不是总能行得通的, ...

  7. rsync命令来实现将服务器端的文件备份到客户端

    rsync命令来实现将服务器端的文件备份到客户端

  8. sed文本处理--文本行扩展与分割

    原文件: 00 abc sdfdsf1 2 45 3 400 xfd xdfssdf3 322 345 234 处理后文件: 00 abc sdfdsf 1 2 400 abc sdfdsf 5 3 ...

  9. 【宽搜】ECNA 2015 D Rings (Codeforces GYM 100825)

    题目链接: http://codeforces.com/gym/100825 题目大意: 给你一张N*N(N<=100)的图表示一个树桩,'T'为年轮,'.'为空,求每个'T'属于哪一圈年轮,空 ...

  10. [Locked] Generalized Abbreviation

    Write a function to generate the generalized abbreviations of a word. Example:Given word = "wor ...