Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的λ演算得名,也可称为闭包(Closure)。

Lambda 表达式是推动 Java 8 发布的重要新特性,它允许把函数作为一个方法的参数(函数作为参数传递进方法中),下面通过例 1 来理解 Lambda 表达式的概念。

例 1
先定义一个计算数值的接口,代码如下。

// 可计算接口
public interface Calculable {// 计算两个int数值int calculateInt(int a, int b);
}

Calculable 接口只有一个方法 calculateInt,参数是两个 int 类型,返回值也是 int 类型。实现方法代码如下:

public class Test{/*** 通过操作符,进行计算** @param opr 操作符* @return 实现Calculable接口对象*/public static Calculable calculate(char opr) {Calculable result;if (opr == '+') {// 匿名内部类实现Calculable接口13       result = new Calculable() {// 实现加法运算@Override16           public int calculateInt(int a, int b) {return a + b;}};} else {// 匿名内部类实现Calculable接口23         result = new Calculable() {// 实现减法运算@Override26            public int calculateInt(int a, int b) {return a - b;}};}return result;}
}

方法 calculate 中 opr 参数是运算符,返回值是实现 Calculable 接口对象。代码第 13 行和第 23 行都采用匿名内部类实现 Calculable 接口。代码第 16 行实现加法运算。代码第 26 行实现减法运算。

public static void main(String[] args) {int n1 = 10;int n2 = 5;// 实现加法计算Calculable对象
5    Calculable f1 = calculate('+');// 实现减法计算Calculable对象
7    Calculable f2 = calculate('-');// 调用calculateInt方法进行加法计算
9    System.out.println(n1 + "+" + n2 + "=" + f1.calculateInt(n1, n2));// System.out.printf("%d + %d = %d \n", n1, n2, f1.calculateInt(n1, n2));// 调用calculateInt方法进行减法计算
12    System.out.println(n1 + "-" + n2 + "=" + f1.calculateInt(n1, n2));// System.out.printf("%d - %d = %d \n", n1, n2, f2.calculateInt(n1, n2));
}

代码第 5 行中 f1 是实现加法计算 Calculable 对象,代码第 7 行中 f2 是实现减法计算 Calculable 对象。代码第 9 行和第 12 行才进行方法调用。

上述代码中列出了两种输出方式,下面简单介绍一下 Java 中常见的输出函数:

  1. printf 主要继承了C语言中 printf 的一些特性,可以进行格式化输出。
  2. print 就是一般的标准输出,但是不换行。
  3. println 和 print 基本没什么差别,就是最后会换行。

输出结果如下:

10+5=15
10-5=15

例 1 使用匿名内部类的方法 calculate 代码很臃肿,Java 8 采用 Lambda 表达式可以替代匿名内部类。修改之后的通用方法 calculate 代码如下:

/**
* 通过操作符,进行计算
* @param opr 操作符
* @return 实现Calculable接口对象
*/
public static Calculable calculate(char opr) {Calculable result;if (opr == '+') {// Lambda表达式实现Calculable接口
10        result = (int a, int b) -> {return a + b;};} else {// Lambda表达式实现Calculable接口
15        result = (int a, int b) -> {return a - b;};}return result;
}

代码第 10 行和第 15 行用 Lambda 表达式替代匿名内部类,可见代码变得简洁。通过以上示例我们发现,Lambda 表达式是一个匿名函数(方法)代码块,可以作为表达式、方法参数和方法返回值

Lambda 表达式标准语法形式如下:

(参数列表) -> {// Lambda表达式体
}

->被称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分:

  • 左侧:Lambda 表达式的参数列表。
  • 右侧:Lambda 表达式中所需执行的功能,用{ }包起来,即 Lambda 体。

Java Lambda 表达式的优缺点

优点:

代码简洁,开发迅速
方便函数式编程
非常容易进行并行计算
Java 引入 Lambda,改善了集合操作(引入 Stream API)

缺点:

代码可读性变差
在非并行计算中,很多计算未必有传统的 for 性能要高
不容易进行调试

函数式接口

Lambda 表达式实现的接口不是普通的接口,而是函数式接口。如果一个接口中,有且只有一个抽象的方法(Object 类中的方法不包括在内),那这个接口就可以被看做是函数式接口。这种接口只能有一个方法。如果接口中声明多个抽象方法,那么 Lambda 表达式会发生编译错误:

The target type of this expression must be a functional interface

这说明该接口不是函数式接口,为了防止在函数式接口中声明多个抽象方法,Java 8 提供了一个声明函数式接口注解 @FunctionalInterface,示例代码如下。

// 可计算接口
@FunctionalInterface
public interface Calculable {// 计算两个int数值int calculateInt(int a, int b);
}

在接口之前使用 @FunctionalInterface 注解修饰,那么试图增加一个抽象方法时会发生编译错误。但可以添加默认方法和静态方法。

@FunctionalInterface 注解与 @Override 注解的作用类似。Java 8 中专门为函数式接口引入了一个新的注解 @FunctionalInterface。该注解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。

提示:Lambda 表达式是一个匿名方法代码,Java 中的方法必须声明在类或接口中,那么 Lambda 表达式所实现的匿名方法是在函数式接口中声明的。

1.21 Lambda表达式相关推荐

  1. 课时21:函数:lambda表达式

    目录: 一.lambda表达式 二.介绍两个BIF:filter()和map() 三.课时21课后习题及答案 ********************* 一.lambda表达式 *********** ...

  2. C++11:Lambda表达式(匿名函数)理解

    C++在C11标准中引入了匿名函数,即没有名字的临时函数,又称之为lambda表达式.lambda表达式 实质上是创建一个匿名函数/对象.即你可以理解为(Lambda 表达式实际上是一个函数,只是它没 ...

  3. Python3中lambda表达式介绍

    Python3中的lambda表达式或lambda函数是匿名函数(anonymous function),意味着该函数没有名称.def关键字用于在Python3中创建一个普通函数,类似地,lambda ...

  4. Lambda表达式的运用(详尽版)

    Lambda表达式是Java JDK8发布的最新特性,它极大地简化了定义匿名内部类时要写的代码,使代码变得更加简洁紧凑. 我们知道定义匿名内部类时要紧跟创建对象,接着要实现接口或重写父类中的抽象方法, ...

  5. 刻意练习:Python基础 -- Task05. 函数与Lambda表达式

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  6. 零基础入门学习Python(20)-lambda表达式、filter()、map() BIF

    lambda表达式 lambda关键字的使用 Python允许使用lambda关键字来创建匿名函数 基本语法:使用冒号(:)分隔函数的参数及返回值,冒号左边放置函数的参数,如果有多个参数,使用逗号(, ...

  7. jdk8新特性 lambda表达式详解

    本文主要讲到的内容有: 一- 前言 二- 背景 三- lambda表达式的语法 四- Lambda程序例子 4-1 Runnable Lambda 4-2 Comparator Lambda 4-3 ...

  8. Java8之——简洁优雅的Lambda表达式

    Java8发布之后,Lambda表达式,Stream等等之类的字眼边慢慢出现在我们字眼.就像是Java7出现了之后,大家看到了"钻石语法",看到了try-with-resource ...

  9. C# Lambda表达式

    "Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型, ...

最新文章

  1. Torchvision目标检测模型训练过程记录
  2. 在ASP.NET AJAX中使用应用程序服务和本地化(3):用户个性化组件ProfileService
  3. python接口自动化(二十五)--unittest断言——下(详解)
  4. python3.5.2安装pygame_【闲来无事,py写game】Mac-Python3.5安装pygame 1.9.2 小计
  5. LeetCode 3. 无重复字符的最长子串(滑动窗口+哈希)
  6. Qt文档阅读笔记-QThread::setPriority(Priority priority)官方解析及实例
  7. 常用JavaScript函数 16 - 30(自我总结)
  8. 造成OOM的原因有哪几种?
  9. UI自定义UITableView的右侧索引
  10. HTTP协议—状态码(思维导图速查)
  11. 一个三年Java程序员的面试总结!
  12. type与instance区别
  13. 智能指针shared_ptr, auto_ptr, scoped_ptr, weak_ptr总结
  14. 一个LaTeX论文模板
  15. social network 学习心得
  16. Aspose.Words五 MergeField
  17. Gameloft的移动游戏王者之路
  18. 性价比高一点的蓝牙耳机有哪几款?高性价比蓝牙耳机推荐
  19. 福瑞泰克完成数亿元B+轮融资,行泊一体+NOA进入大规模量产周期
  20. Android计步器算法实现

热门文章

  1. Algorithm之PrA:PrA之nLP非线性规划算法经典案例剖析+Matlab编程实现
  2. Py之pytest-shutil:Python库之pytest-shutil简介、安装、使用方法之详细攻略
  3. PostgreSQL 务实应用(三/5)分表复制
  4. selenium V1.0和V2.0差别对比
  5. Centos-挂载和卸载分区-mount
  6. 使用 NuGet 管理我们的程序集 - 预发行版
  7. [转]对于非数据库字段的查询过滤以及app_query.append的用法
  8. 10-10数组的介绍
  9. 一个回车引发的编译错误
  10. stdthread(8)并发recursive_mutex 递归锁