作为参数使用Lambda表达式

Lambda 表达式一种常见的用途就是作为参数传递给方法,这需要声明参数的类型声明为函数式接口类型。示例代码如下:

public static void main(String[] args) {int n1 = 10;int n2 = 5;// 打印加法计算结果display((a, b) -> {return a + b;
7    }, n1, n2);// 打印减法计算结果
9    display((a, b) -> a - b, n1, n2);
}
/**
* 打印计算结果
*
* @param calc Lambda表达式
* @param n1   操作数1
* @param n2   操作数2
*/
19 public static void display(Calculable calc, int n1, int n2) {System.out.println(calc.calculateInt(n1, n2));
}

上述代码第 19 行定义 display 打印计算结果方法,其中参数 calc 类型是 Calculable,这个参数即可以接收实现 Calculable 接口的对象,也可以接收 Lambda 表达式,因为 Calculable 是函数式接口。 代码第 7 行和第 9 行两次调用 display 方法,它们第一个参数都是 Lambda 表达式。

访问变量

Lambda 表达式可以访问所在外层作用域定义的变量,包括成员变量和局部变量。

访问成员变量

成员变量包括实例成员变量和静态成员变量。在 Lambda 表达式中可以访问这些成员变量,此时的 Lambda 表达式与普通方法一样,可以读取成员变量,也可以修改成员变量。

public class LambdaDemo {// 实例成员变量private int value = 10;// 静态成员变量private static int staticValue = 5;// 静态方法,进行加法运算
8    public static Calculable add() {Calculable result = (int a, int b) -> {// 访问静态成员变量,不能访问实例成员变量staticValue++;int c = a + b + staticValue;
13            // this.value;return c;};return result;}// 实例方法,进行减法运算
20    public Calculable sub() {Calculable result = (int a, int b) -> {// 访问静态成员变量和实例成员变量
23            staticValue++;this.value++;int c = a - b - staticValue - this.value;return c;};return result;}
}

LambdaDemo 类中声明一个实例成员变量 value 和一个静态成员变量 staticValue。此外,还声明了静态方法 add(见代码第 8 行)和实例方法 sub(见代码第 20 行)。add 方法是静态方法,静态方法中不能访问实例成员变量,所以代码第 13 行的 Lambda 表达式中也不能访问实例成员变量,也不能访问实例成员方法。

sub 方法是实例方法,实例方法中能够访问静态成员变量和实例成员变量,所以代码第 23 行的 Lambda 表达式中可以访问这些变量,当然实例方法和静态方法也可以访问。当访问实例成员变量或实例方法时可以使用 this,如果不与局部变量发生冲突情况下可以省略 this。

访问局部变量

对于成员变量的访问 Lambda 表达式与普通方法没有区别,但是访问局部变量时,变量必须是 final 类型的(不可改变)。

示例代码如下:

public class LambdaDemo {// 实例成员变量private int value = 10;// 静态成员变量private static int staticValue = 5;// 静态方法,进行加法运算public static Calculable add() {// 局部变量
10        int localValue = 20;Calculable result = (int a, int b) -> {12            // localValue++;// 编译错误
14            int c = a + b + localValue;return c;};return result;}// 实例方法,进行减法运算public Calculable sub() {// final局部变量
23        final int localValue = 20;Calculable result = (int a, int b) -> {25            int c = a - b - staticValue - this.value;
26            // localValue = c;// 编译错误return c;};return result;}
}

上述代码第 10 行和第 23 行都声明一个局部变量 localValue,Lambda 表达式中访问这个变量,如代码第 14 行和第 25 行。不管这个变量是否显式地使用 final 修饰,它都不能在 Lambda 表达式中修改变量,所以代码第 12 行和第 26 行如果去掉注释会发生编译错误。

Lambda 表达式只能访问局部变量而不能修改,否则会发生编译错误,但对静态变量和成员变量可读可写。

方法引用

方法引用可以理解为 Lambda 表达式的快捷写法,它比 Lambda 表达式更加的简洁,可读性更高,有很好的重用性。如果实现比较简单,复用的地方又不多,推荐使用 Lambda 表达式,否则应该使用方法引用。

Java 8 之后增加了双冒号::运算符,该运算符用于“方法引用”,注意不是调用方法。“方法引用”虽然没有直接使用 Lambda 表达式,但也与 Lambda 表达式有关,与函数式接口有关。 方法引用的语法格式如下:

ObjectRef::methodName

其中,ObjectRef 是类名或者实例名,methodName 是相应的方法名。

注意:被引用方法的参数列表和返回值类型,必须与函数式接口方法参数列表和方法返回值类型一致,示例代码如下。

public class LambdaDemo {// 静态方法,进行加法运算// 参数列表要与函数式接口方法calculateInt(int a, int b)兼容public static int add(int a, int b) {return a + b;}// 实例方法,进行减法运算// 参数列表要与函数式接口方法calculateInt(int a, int b)兼容public int sub(int a, int b) {return a - b;}
}

LambdaDemo 类中提供了一个静态方法 add,一个实例方法 sub。这两个方法必须与函数式接口方法参数列表一致,方法返回值类型也要保持一致。

public class HelloWorld {public static void main(String[] args) {int n1 = 10;int n2 = 5;// 打印加法计算结果
6        display(LambdaDemo::add, n1, n2);LambdaDemo d = new LambdaDemo();// 打印减法计算结果
9        display(d::sub, n1, n2);}/*** 打印计算结果** @param calc Lambda表达式* @param n1   操作数1* @param n2   操作数2*/
18    public static void display(Calculable calc, int n1, int n2) {System.out.println(calc.calculateInt(n1, n2));}
}

代码第 18 行声明 display 方法,第一个参数 calc 是 Calculable 类型,它可以接受三种对象:Calculable 实现对象、Lambda 表达式和方法引用。代码第 6 行中第一个实际参数LambdaDemo::add是静态方法的方法引用。代码第 9 行中第一个实际参数d::sub,是实例方法的方法引用,d 是 LambdaDemo 实例。

提示:代码第 6 行的LambdaDemo::add和第 9 行的d::sub是方法引用,此时并没有调用方法,只是将引用传递给 display 方法,在 display 方法中才真正调用方法。

1.23 Lambda表达式的使用相关推荐

  1. Kotlin学习笔记23 协程part3 lambda表达式深入 挂起函数 全局协程

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 1 lambda表达式深入 /*** lambda 表达式深入* 当函数参数是函数时 并且该函数只有一个参数 可以不传入任 ...

  2. Java8中Lambda表达式的10个例子

    Java8中Lambda表达式的10个例子  例1 用Lambda表达式实现Runnable接口 Java代码   //Before Java 8: new Thread(new Runnable() ...

  3. Lambda表达式可以被转换为委托类型

    void Main() { //向Users类中增加两人; List<Users> user=new List<Users>{ new Users{ID=1,Name=&quo ...

  4. 10个Java 8 Lambda表达式经典示例

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

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

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

  6. 深入理解Java 8 Lambda表达式(Oracle官方文档版)

    Java 8 问世三年了,9马上也要问世了,所以,嗯,我要开始学8了-- 官方文档:http://docs.oracle.com/javase/tutorial/java/javaOO/lambdae ...

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

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

  8. C# Lambda表达式

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

  9. SqlDataReader生成动态Lambda表达式

    上一扁使用动态lambda表达式来将DataTable转换成实体,比直接用反射快了不少.主要是首行转换的时候动态生成了委托. 后面的转换都是直接调用委托,省去了多次用反射带来的性能损失. 今天在对Sq ...

最新文章

  1. 【MySQL】Dockerfile书写简单示例
  2. centos 自动挂载磁盘
  3. 在 Linux 命令行中使用 tcpdump 抓包
  4. 如何屏蔽PHP浏览器头信息X-Powered-By
  5. 【论文阅读】A Gentle Introduction to Graph Neural Networks [图神经网络入门](2)
  6. mysql集群初始化配置_集群Cluster MySQL的安装配置和使用
  7. 逆向映射是干嘛的anon_vma, vma, anon_vma_chain
  8. LeetCode 1758. 生成交替二进制字符串的最少操作数(DP)
  9. MySQL---分组查询
  10. N60E-O发布 不同CPU或将改变服务器市场?
  11. java addmonth_JAVA:int month = n.get(Calendar.MONTH)+1;为何要加1?
  12. u盘安装ubuntu server 14.04 以及No CD-ROM drive was detected 错误
  13. TOGAF9.2 第I部分 第1章简介
  14. Django serializer 方法补充之:depth 与字段生成超链接
  15. IDEA的类注释模板
  16. 提升 10 倍!阿里云对象存储 OSS 可用性 SLA 技术揭秘
  17. 李广难封–有感于团队建设
  18. LED驱动电路设计及原理分析
  19. 受益于人工智能的发展,人们可以以前所未有的时空分辨率系统地观察神经活动
  20. QQ揭秘:如何实现窗体靠边隐藏?【低调赠送:QQ高仿版GG 4.2 最新源码】

热门文章

  1. BC:带你温习并解读《中国区块链技术和应用发展白皮书》—区块链标准体系框架
  2. Matlab:利用Matlab实现布朗运动模拟
  3. MAT之ACA:利用ACA解决TSP优化最佳路径问题
  4. Hyperopt中文文档:Cite引用
  5. MQ各个元素的详细理解
  6. 毕业设计——学术交流管理系统的设计与实现-1
  7. CentOS 安装MySQL rpm方式安装
  8. 04_Struts2标签
  9. 拓扑排序之变量序列代码
  10. 我校四名学生在全国中学生物理竞赛中勇夺一金三银并全部直保清华