• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Java 8系列之Lambda实践步骤(二)

技术杂谈 勤劳的小蚂蚁 3个月前 (02-07) 70次浏览 已收录 0个评论 扫描二维码

1

关于实践


这里依旧我们通过学生筛选的例子,看看在实践中如何通过Lambda表达式使得代码更加灵活、简洁。现在我们需要从全体学生中,将英语成绩在95分以上的学生筛选出来。筛选代码如下:


现在的代码的确满足了我们的需求,但如果我们需要将筛选分数改成80分,并且95分的筛选方法以后还有可能需要用时该怎么办?如果在实际开发中,你可能也不会想使用策略模式(尽管还是很啰嗦),更直接的是直接写出来studentFilterByEnglish95()和studentFilterByEnglish80()两个函数来满足需求了。那现在我需要过滤75分的学生,需要过滤数学成绩,需要过滤科学成绩呢?是否会有一堆啰里啰嗦的过滤函数被写出来,看过上一节的同学一定明白,此时最好的处理思路是传递学生的判断代码,即行为参数化,重用过滤执行机制。

Step1 : 行为参数化

传递行为正是Lambda表达式的独门秘诀,我们希望结合Lambda表达式,新的学生过滤函数使用方式应该如下:


Step2 :函数式接口声明

在上一篇文章中我们说过,Lambda的使用环境上下文必须是函数式接口,很显然学生判断过滤代码只有if判断条件需要根据条件更改 ,所以我们现在需要一个能与 Student -> boolean匹配的函数式接口的声明,并将该接口作为studentFilter的参数,便可以实现行为的传递了,代码如下:

现在我们就可以将StudentFilter这一函数式接口作为学生过滤函数的参数,传递给它了:

Step3 :行为执行

结合StudentFilter接口,改用StudentFilter.test()用于学生的判断:


Step4 : 传递Lambda

此时,我们便可以使用studentFilter方法来传递Lambda表达式了,正如Step1中我们所期望的使用方式那样使用,只需要注意Lambda的函数签名必须与函数式接口声明的抽象方法对应。


2

关于Lambda表达式的类型推断

在Java 7中,已经引入了 菱形运算符(<>),Java可以利用泛型从上下文中推断出合适的类型参数的特性。利用该特性,Java编译器同样可以在Lambda表达式中,结合函数式接口的声明,便可以推断出参数列表的参数类型,从而可以写出更加简洁的Lambda表达式,如下:

可以看到Java对于Lambda表达式支持类型推断,这些年Java的确从C#的语法特性中汲取了很多好用的特性。

3

Lambda的变量访问

在我们目前遇到的所有示例中的Lambda主体中,都只是用了参数列表中的变量,其实Lambda是支持引用外部变量的。但是对于外部变量的引用Lambda是有限制的,如果外部变量是实例变量或静态变量可以直接使用,但如果是局部变量,那局部变量必须是final或effectively final才可以引用,如下就无法通过java编译:


为什么会有这样的限制?这要通过JMM来考虑,在JMM中局部变量与实例变量在Java内存中存储在不同的内存区域,实例变量存储在Java堆中,而局部变量存储在线程栈中。如果Lambda直接访问局部变量,而且Lambda是在一个线程中使用,则使用Lambda的线程可能会在局部变量已经被释放的情况下再去访问。而在JMM模型中,线程对于实例变量的操作都是副本操作,然后通过副本与主存之间的刷新进行同步的。final域的添加,确保了该局部变量只会有一个不变值,从而在多线程情况下的线程安全性,为什么String类型是线程安全的?就是因为它只会存在一个值。

在使用Lambda表达式之前,一定要明白自己实现的是一个什么样的函数接口,本文我们根据函数式接口的语法规则定义了StudentFilter函数式接口,从而实现了可以在filter方法中传递行为。但是在开发中,我们常常会用到类似签名接口,例如 () -> boolean, (T) -> void, ( T ) -> ( T )等等,Java 8将一些通用形式的接口进行了定义,我们将在下节来讨论这些JDK中的函数式接口。


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Java 8系列之Lambda实践步骤(二)
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00