文档章节

Java 8 和 Scala 中的 Lambda 表达式

散装海盗
 散装海盗
发布于 2012/07/11 11:28
字数 1492
阅读 2148
收藏 18

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

这篇文章是infoQ上面关于java 8 和 scala 特性比较的一部分,原文实在是太长了,,分段翻译,先贴出来一部分,翻译的不好,欢迎拍砖。。。原文地址 

Java8 终于要支持Lambda表达式!自2009年以来Lambda表达式已经在Lambda项目中被支持。在那时候,Lambda表达式仍被称为Java闭包。在我们进入一些代码示例以前,先来解释下为什么Lambda表达式在Java程序员中广受欢迎。

1、为什么使用Lambda表达式

Lambda表达式通常使用在图形用户界面(GUI)的开发中。一般来说,GUI编程将程序行为和事件做连接。比如,当用户按下一个按钮(触发一个事件),你的程序就需要去执行某些行为,可能是将一些数据储存到一个数据存储器中。在Swing中,可以使用ActionListener来实现:
class ButtonHandler implements ActionListener {
	public void actionPerformed(ActionEvent e) {
		//do something
	}
}

class UIBuilder {
	public UIBuilder() {
		button.addActionListener(new ButtonHandler());
	}
}

这个例子表明了 ButtonHandler 类作为一个回调替换的用法。在这里 ButtonHandler 类仅包含 ActionListener 接口定义的 actionPerformed 方法。我们可以使用匿名内部类来简化代码:
class UIBuilder {
	public UIBuilder() {
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				//do something
			}
		})
	}
}

这样代码简洁多了。更仔细的去看代码时,就会发现我们还创建一个只生成一个实例的类,而这个实例也仅仅持有一个独立的方法。这恰好是Lambda表达式所能解决的其中一类问题。

2、Lambda表达式代替函数

一个lambda表达式从字面上讲就是一个函数。它定义了一个函数的输入参数和函数体。Java 8 中的,lambda表达式语法尚未确定,不过大致应该类似这个样子的:
(type parameter) -> function_body

一个具体的例子:
(String s1, String s2) -> s1.length() - s2.length();

这个lambda表达式用来计算两个字符串的长度差。还有一些扩展的语法,比如避免参数的类型定义(我们马上见看到例子)还有使用{和}来支持多行定义。
Collections.sort() 方法是lambda表达的理想例子。它允许我们将字符串按照长度排序:
List<String> list = Array.asList("loooooong", "short", "tiny");
Collections.sort(list, (String s1, String s2) -> s1.length() - s2.length());
> "tiny", "short", "loooooong".

所以,不像现在java必须要求的向sort方法输入一个已经实现的Comparator(比较器)而是传送一个lambda表达式我们就可以得到相同的结果。

3、Lambda表达式代替闭包

lambda表达式有许多有趣的特性。其中之一是,它们是闭包。一个闭包允许函数访问直接词法作用域之外的变量。
String outer = "java 8"
(String s1) -> s1.length() - outer.length()

在例子中,lambda表达式访问了字符串 outer 这个作用域之外定义的变量。对于内联闭包来说这是很难做到的。

4、Lambda表达式也支持类型推论

类型推论是java 7 引入的但它同样适用于lambda表达式。简单来说,类型推论意味着程序员可以在任意一个编译器能够自动推断出类型的地方省略类型定义。
如果类型推论能够应用到前面的排序lambda表达式上,那么它就能写成下面的样子:
List<String> list = Arrays.asList(...);
Collections.sort(list, (s1, s2) -> s1.length()-s2.length());

就像你所见到的一样,参数s1和s2的类型被省略了。因为编译器知道list是一个字符串集合,它知道被用来作为比较器的lambda表达式必定是相同的类型。因此,这个类型不需要显式地声明,即使你有这么做的自由。
类型推论的主要优势就是减少样板代码,如果编译器可以为我们识别类型,为什么我们必须自己定义它们。

5、珍爱Lambda表达式,远离匿名内部类

我们来体会下,为何lambda表达式和类型推论有助于简化我们前面所提到的回调例子:
class UIBuilder {
	public UIBuilder() {
		button.addActionListener(e -> //process ActionEvent e)
	}
}

我们下载直接传送一个lambda表达式进入 addActionListener 方法来代替前面定义的持有回调方法的类。除了减少模板代码和提高可读性以外,它使我们直接表达我们唯一感兴趣的事情:处理事件。
在我们了解lambda表达式更多优势之前,先来看看在Scala中的lambda表达式副本。

6、Scala中的Lambda表达式

在函数式编程中,函数是基本的构造块。Scala融合了java中的面向对象编程和函数式编程。在Scala中,一个lambda表达式是种叫做“函数”或者“函数文本”。Scala中的函数属于一等公民。它们可以被分配给vals或者vars(最终变量或者非最终变量),它们可以作为其他函数的参数,也可以组合成新的函数。
在Scala中一个函数文本写成如下形式:
(argument) => //funtion body

举例来说,前面提到的java 用来计算两个字符串长度差的 lambda 表达式,在Scala中写作如下:
(s1: String, s2 :String) => s1.length - s2.length

Scala中的函数文本也是闭包。它可以访问在直接词法作用域之外定义的变量。
val outer =10
val myFuncLiteral = (y: Int) => y * outer
val result = myFuncLiteral(2)
> 20

这个例子结果是20.
正如你所见,我们将函数文本分配给了变量 myFuncLiteral。
java 8 的lambda表达式和Scala的函数文本在语法和语义上的相似性是十分明显的。从语义上讲它们是相同的,而语法上的唯一不同就是箭头符号(java8 ->, scala =>)和我们没有提到的简化符号。

本文转载自:http://www.infoq.com/articles/java-8-vs-scala

散装海盗

散装海盗

粉丝 11
博文 13
码字总数 3970
作品 0
朝阳
程序员
私信 提问
了解一下Java 8 (一)

2015年公司发展迅速,于是大量的时间花费在招聘上。招聘工程师,必然需要了解候选人的技术能力,尤其是对自己使用的技术的了解程度。优秀的工程师都需要知其然,也知其所以然,否则遇到技术难...

TalkingData
2016/01/20
1K
8
Java 8会干掉Scala吗?

2014-04-15 孙镜涛 InfoQ 最令人期待的Java 8已于2014年3月18日发布,该版本包含很多令人兴奋的新特性,被认为是自Java 5发布以来对Java做出的最大改变。对于开发者而言,最值得注意的特性包...

Yamazaki
2014/04/23
2
0
Java 8新增特性优缺点

Java 8于今年三月份正式发布了。那么它是否如我们之前所期待的那样呢?下面我们就一一查看Java8新增特性的优缺点吧。 Java 8试图“创新”,根据 微软对这个词的定义,就是把其他框架或语言里...

Emilypz
2015/09/25
898
1
Java 8新增特性优缺点

Java 8于今年三月份正式发布了。那么它是否如我们之前所期待的那样呢?下面我们就一一查看Java8新增特性的优缺点吧。 Java 8试图“创新”,根据 微软对这个词的定义,就是把其他框架或语言里...

Emilypz
2015/09/25
606
1
Java8学习:Lambda表达式与Functional接口

Lambda表达式(也称为闭包)是整个Java 8发行版中最受期待的在Java语言层面上的改变,Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据:函数式程序员对...

王爵nice
2014/07/03
0
1

没有更多内容

加载失败,请刷新页面

加载更多

采购单品汇总_华南.xlsx

import pandas as pdimport matplotlib.pyplot as pltimport matplotlib as mp1mp1.rcParams["font.family"] = "STFangsong"# 加载《销售》表数据df1 = pd.read_excel(r"C:\Us......

龙玉滕
今天
5
0
OSChina 周五乱弹 —— 一次四千 要4次还能多给一千

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @这次装个文艺青年吧 :#今日歌曲推荐# 分享金志文的单曲《远走高飞》: 版权又回来了现在听歌得好几个软件 《远走高飞》- 金志文 手机党少年们...

小小编辑
今天
7
0
Spring Cloud Alibaba 实战(十) - Spring Cloud GateWay

> 本文主要内容是:为什么要使用网关,整合Gateway,Gateway核心学习:Route,Predicate,Filter,最后使用Gateway聚合微服务请求 先总结至此的架构 1 网关的价值 不使用网关行嘛? 各个请求直接打在...

JavaEdge
今天
4
0
【CKB.DEV 茶话会】第二期:聊聊 CKB 钱包和 Nervos DAO 全流程

CKB.DEV 茶话会第二期:聊聊 CKB 钱包和 Nervos DAO 全流程 为了鼓励更多优秀的开发者和研究人员参与到 CKB 的开发和生态建设中去,我们希望组织一系列 CKB Developer Seminar(CKB.DEV 茶话...

NervosCommunity
今天
4
0
聊聊rocketmq的HAClient

序 本文主要研究一下rocketmq的HAClient HAClient rocketmq-all-4.6.0-source-release/store/src/main/java/org/apache/rocketmq/store/ha/HAService.java class HAClient extends Serv......

go4it
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部