文档章节

Java8 和 Scala 中的高阶函数,可重用的构建快

散装海盗
 散装海盗
发布于 2012/07/13 11:45
字数 943
阅读 907
收藏 7

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

函数文本最大的优势就是可以像字符串或者对象等其他文本(literal)一样传送它。这种特性为构建高度紧凑和可重用代码提供无限的可能性。

1、我们的第一个高阶函数

当我们将一个函数文本传送给一个方法的时候,我们最主要的是一个接收方法参数的方法(这个确实很绕-_-|||),这类方法就叫做高阶函数。上文Swing例子中提到的 addActionListener 方法恰好属于这类。我们还可以定义自己的高阶函数来为自己提供许多便利。让我们看一个简单的例子:

def measure[T](func:=>T):T {
	val start = System.nanoTime()
	val result = func
	val elapsed = System.nanoTime() - start;
	print("The execution of this call took: %s ns".format(elapsed));
	result
}

在这个例子中,我们声明了一个名为measure的方法用来计算这个名为func的函数文本的回调所需要的时间。func 方法的签名(signature)是它不接收任何参数并且返回一个泛型类型T。正如你所看到的,Scala中的函数并不一定需要参数尽管它们能够——而且往往也含有参数。

现在我们可以向 measure 方法中传递任何函数文本(或者方法)。

def myCallback = {
	Thread.sleep(1000)
	"I just took a poewrnap"
}

val result = measure(myCallback);

> The execution of this call took: 100244900 ns

从概念的角度讲我们所做的,就是将计算方法调用时间和实际的运算区分开来。我们构造了两块可以重用、松散耦合、类似于拦截器(interceptor)的代码块(measure和myCallback)

2、通过高阶函数实现重用

先看一个假设的例子,两个可重用构造略紧耦合:

def doWithContact(fileName:String, handle:Contact => Unit):Unit = {
	try {
		val contactStr = io.Source.fromFile(fileName).mkString
		val contact = AContactParser.parse(contactStr)
		handle(contact)
	}
	catch {
		case e: IOException => println("couldn't load contact file: " + e);
		case e: ParseException => println("coulnd't parse contact file: " + e);
	}
}

doWithContact 方法从文件中读取电子名片之类的联系方式然后将数据提供给一个解析器(parser)将数据转化成为联系领域的对象。然后这个对象被传递给一个函数文本回调 handle。 doWithContact 方法 很函数文本均返回 Unit 类型,等同于java中的返回void的方法。

现在,我们可以定义各种各样的可以传递给 doWithContact 的回调函数:

val storeCallback = (c:Contact) => ContactDao.save(c)
val sendCallback = (c:Contact) => {
	val msgBody = AConverter.convert(c)
	RestService.send(msgBody)
}
val combineCallback = (c:Contact) => {

	storeCallback(c)

	sendCallback(c)

}

doWithContact("custerX.vcf", storeCallback)
doWithContact("custerY.vcf", sendCallback)
doWithContact("custerZ.vcf", combineCallback)
doWithContact("custerZ.vcf", combineCallback)

回调函数也可以通过内联传递:

doWithContact("custerW.vcf", (c:Contact) => ContactDao.save(c))

3、Java 8 中的高阶函数

java 8 中的等效实现看起来十分相似——使用目前的语法建议:

public interface Block<T> {
	void apply(T t);
}

public void doWithContact(String fileName, Block<Contact> block) {
	try {
		String contacStr = FileUtils.readFileToString(new File(fileName));
		Contact.apply(contact);
		block.apply(contact);
	}
	catch (IOException e) {
		System.out.println("cloudn't load contact file: " + e.getMessage());
	}	
	catch (ParseException e) {
		System.out.println("cloudn't parse contact file: " + e.getMessage());
	}
}

//usage
doWithContact("custerX.vcf", c -> ContactDao.save(c))

4、使用高阶函数的益处

正如你见到的,函数帮助我们干净地将对象的创建和处理区分开来。通过这种方法,新的业务逻辑处理对象就可以轻易的添加进来而没有必要同对象创建逻辑相耦合。

结果就是,我们通过使用高阶函数来使我们的代码保持DRY(Dont't Repeat Yourself) 因而,程序员可以从一个非常细粒度的代码重用中获得最佳利益。

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

散装海盗

散装海盗

粉丝 11
博文 13
码字总数 3970
作品 0
朝阳
程序员
私信 提问
Java 8 vs. Scala(一): Lambda表达式

【编者按】虽然 Java 深得大量开发者喜爱,但是对比其他现代编程语言,其语法确实略显冗长。但是通过 Java8,直接利用 lambda 表达式就能编写出既可读又简洁的代码。作者 Hussachai Puripunp...

OneAPM蓝海讯通
2015/11/30
34
0
Scala开发者的Spring-Boot快速上手指南 02:Scala惯用法

(这是一篇迟来的文章,从3月份计划到成文花了5个月多……以后需要避免这样的低效率。) 之前写第一篇文章时,只是想试试在Spring中使用Scala。但现在随着工作的需要,已经决定在应用层基于Spr...

羊八井
2016/10/12
226
0
Spark入门到精通视频学习资料--第一章、Scala基础与实践

第一章、Scala基础与实践(3讲) Scala编程语言抓住了很多开发者的眼球。如果你粗略浏览Scala的网站,你会觉得Scala是一种纯粹的面向对象编程语言,而又无缝地结合了命令式和函数式的编程风格...

dongzhumao
2015/02/06
0
0
Scala入门-大数据云计算下的开发语言

Scala编程语言抓住了很多开发者的眼球。如果你粗略浏览Scala的网站,你会觉得Scala是一种纯粹的 面向对象编程语言,而又无缝地结合了命令式编程和 函数式编程风格。Christopher Diggins认为:...

liwei2000
2018/06/30
59
0
stream in java8

如果使用过scala,使用scala函数编程思想处理数据,那酸爽谁用谁知道。使用java老觉得不得劲,但java8借用了scala的思想,引入了函数编程思想,那就是stream,随后我们慢慢体验她的妙处。 Ja...

jacksu在简书
2018/01/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

今日头条技术架构分析,看这篇就对了!

点击上方 "程序员小乐"关注, 星标或置顶一起成长 每天凌晨00点00分, 第一时间与你相约 每日英文 Anywhere, it is a good in the past, recall the number of times many, all would be ligh......

吧主
7分钟前
20
0
影响K8S Pod分配和调度策略的两大关键特性

在Kubernetes中有一个最复杂的调度器可以处理pod的分配策略。基于在pod规范中所提及的资源需求,Kubernetes调度器会自动选择最合适的节点来运行pod。 但在许多实际场景下,我们必须干预调度过...

RancherLabs
9分钟前
25
0
Linux笔记

Linux常用命令之chmod修改文件权限777和754 示例:chmod 777 /etc/squid 运行命令后,squid文件夹(目录)的权限就被修改为777(可读可写可执行)。...

owenzhang24
13分钟前
11
0
教你如何在CentOS7系统上安装postgreSQL11

本文教你如何在CentOS7系统上安装postgreSQL11。 1.添加PostgreSQL Yum存储库 sudo yum install https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-centos11-11-......

Linux就该这么学
20分钟前
37
0
欧盟将禁止公共场所人脸识别:谷歌支持,微软反对

   来源:新浪、VB   近日,彭博社披露的一份欧盟人工智能“白皮书”草案显示,欧盟计划对人工智能开发者提出具有法律约束力的新要求,以确保现代科技的开发和使用符合道德规范。    ...

水果黄瓜
24分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部