论函数式编程在JAVA程序中的应用

2015-12-07 11:41连洁
电脑知识与技术 2015年6期
关键词:应用

连洁

摘要:函数式编程已经成为当前最流行的编程模式之一,根据JAVA8最新标准,介绍了lambda表达式对函数式编程的支持,并探讨了Stream类在应用开发中的使用方式,对lambda表达式的应用模式进行了探讨。

关键词:函数式;Java程序;应用

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)06-0099-02

函数式编程(functional programming)作为当前最流行的编程规范之一,主流语言都对其进行了支持,作为编程领域最重要的JAVA语言,也在最新的JDK8中新增了相关特性,这就是lambda(λ)表达式及Stream类。它使得JAVA语言进一步与当今流行趋势结合,增强了JAVA语言的表现力,拓展了它的应用范围,优化了程序的结构与可读性

1 函数式编程简介

函数式编程(functional programming)是一种编程模式,旨在将运算过程尽量写成一系列嵌套的函数调用。在形式上,函数式编程允许将函数作为参数和返回值;在机制上,函数式编程在执行时进行惰性计算(lazy evaluation)和闭包等技术。最主要的优点是不修改状态,可以将任务随意分解,很好的符合了当前多线程、多处理器编程的趋势。

2 JAVA中的lambda表达式

lambda(λ)表达式是JDK8最大的更新之一,旨在引入函数式编程思想优化JAVA程序。其表达形式如下:

(int even, int odd) -> even + odd

在JDK8 中,使用->符号引起表达式,该符号左边为表达式的参数,右边为表达式的行为。Lambda表达式可使用在多种场合,例如作为参数直接传入某个函数:

button.addActionListemer(event->System.out.println(“button clicked!!”));

其中button是一个AWT Button 对象,由此我们可以看出,在传统的需要匿名内部类的地方可由lambda表达式代替,另外,传统的函数参数需要一个对象,而引入了lambda表达式之后,则可以将函数作为参数传入,从而在代码上更加简洁。

引入lambda表达式的优点首先体现着对代码的重构上,传统的JAVA程序有一个重要的概念即匿名内部类,这个类在某些只使用一次即销毁的情况下创建,例如常见的为按钮添加事件

button.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {

System.out.println("button clicked");}

});

但是该代码当中有若干行是纯粹的样板代码,没有任何实际意义,不仅语法冗长,而且破坏了代码的真实意图,而采用lambda表达式改写后,该段代码的目的一目了然,如下所示

button.addActionListener(event->System.out.println("buttonclicked");

其次,lambda表达式配合jdk8新增的的Stream类可以提高程序——特别是循环结构——的执行效率,在JDK8之前,传统的循环结构采用的都是外循环结构,例如试图取得所有来自北京的教师

int count = 0;

for (Teacher teacher : allTeachers) {

if (teacher.isFrom("London")) {

count++;}

}

可以看到,传统方式中,集合内部的数据与外部的循环语句不停的进行交换,外部程序不得不占用一部分空间为结果集做准备,从时间上到空间上都造成了浪费。而经过lambda表达式和Stream改造,原有的外部循环成为内部循环,如下例所示:

long count = allArtists.stream().filter(artist -> artist.isFrom("London")).count();

可以看出,使用lambda表达式后,内部循环只是在符合条件的集合个体中做出标识,不占用额外内存,当程序不发出最后的指令(如要求立即返回结果)时,内部循环不作出任何操作,称为lazy模式,这样就节省了时间。

3 用lambda表达式优化程序

初学者在使用lambda表达式时,可将其应用在集合操作中,优化其操作方式,lambda表达式与Stream类所支持的集合优化有map、filter、flatmap以及reduce等,下面将详细介绍这几种方式。

在这之前,首先定义一个领域模型,模仿现实世界中的某些业务需求,这个领域模型的结构如下

作者Author,包含名称(String name)、所属机构(String origine)和若干成员(String [] members )

著作 Book,包含名称(String name),若干章节(List chapters)和若干作者(List authors)

章节Chapter,包含章节名称(String name)和字数(int chars)

作者集合authors,著作集合books和章节集合chapters。

首先来介绍Stream类中的第一种操作,即map操作,该操作负责将集合当中的元素进行符合条件的转换。例如,需要所有作者的所属机构列表,则使用lambda表达式和Stream代码如下:

Listorigines=authors.Stream().map(author->author. getOrigine()).collect(toList());

第二种常用操作是filter操作,旨在筛选出集合当中符合条件的元素,例如,需要找到所有成员数为1的作者(即该作者不是团队而是个人),代码如下

authors.Stream().filter(author->author.getMembers().length<2);

最后一種常用操作为reduce,该操作类似于数据库中的聚合函数,可对结果进行各种统计,如汇总、小计、总计等,例如要求计算所有所有作者全部著作的总字数,则代码可以如下:

chapters.Stream().map(chapter->chapter.getChars()).reduce(0,(base,acc)->base+acc);

以上介绍了函数式编程在java中的简单应用,作为java8中最重要的新特性,函数式编程极大的简化了代码的编写,使得java这一语言焕发了新的生命力,在未来的开发中,拥有面向对象及面向函数双重特征的java语言必定会发挥更大的作用。

参考文献:

[1] 张迎周, 张卫丰. Haskell:一种现代纯函数式语言[J].南京邮电大学学报:自然科学版,2007(4).

[2] 庞建民, 赵荣彩, 王倩. Haskell语言的惰性计算特性及其应用[J].计算机工程与应用,2006(10).

[3] Richard Warburton. Java 8 Lambdas: Functional Programming For The Masses[M].ORelly, 2014.

猜你喜欢
应用
多媒体技术在小学语文教学中的应用研究
微课的翻转课堂在英语教学中的应用研究