探索Java语言与JVM中的Lambda表达式

发表于:2013-1-06 09:54

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Sha Jiang    来源:51Testing软件测试网采编

  Lambda表达式是自Java SE 5引入泛型以来最重大的Java语言新特性,本文将介绍Lamdba的设计初衷,应用场景与基本语法。

  Lambda表达式,这个名字由该项目的专家组选定,描述了一种新的函数式编程结构,这个即将出现在Java SE 8中的新特性正被大家急切地等待着。有时你也会听到人们使用诸如闭包,函数直接量,匿名函数,及SAM(Single Abstract Method)这样的术语。其中一些术语彼此之间会有一些细微的不同,但基本上它们都指代相同的功能。

  虽然一开始会觉得Lambda表达式看起来很陌生,但很容易就能掌握它。而且为了编写可完全利用现代多核CPU的应用程序,掌握Lambda表达式是至关重要的。

  需要牢记的一个关键概念就是,Lambda表达式是一个很小且能被当作数据进行传递的函数。需要掌握的第二个概念就是,理解集合对象是如何在内部进行遍历的,这种遍历不同于当前已有的外部顺序化遍历。

  在本文中,我们将向你展示Lambda表达式背后的动因,应用示例,当然,还有它的语法。

  为什么你需要Lambda表达式

  程序员需要Lambda表达式的原因主要有三个:

  1、更紧凑的代码

  2、通过提供额外的功能对方法的功能进行修改的能力

  3、更好地支持多核处理

  更紧凑的代码

  Lambda表达式以一种简洁的方式去实现仅有一个方法的Java类。

  例如,如果代码中有大量的匿名内部类--诸如用于UI应用中的监听器与处理器实现,以及用于并发应用中的Callable与Runnable实现--在使用了Lambda表达式之后,将使代码变得非常短,且更易于理解。

  修改方法的能力

  有时,方法不具备我们想要的一些功能。例如,Collection接口中的contains()方法只有当传入的对象确实存在于该集合对象中时才会返回true。但我们无法去干预该方法的功能,比如,若使用不同的大小写方案也可以认为正在查找的字符串存在于这个集合对象中,我们希望此时contains()方法也能返回true。

  简单点儿说,我们所期望做的就是“将我们自己的新代码传入”已有的方法中,然后再调用这个传进去的代码。Lambda表达式提供了一种很好的途径来代表这种被传入已有方法且应该还会被回调的代码。

  更好地支持多核处理

  当今的CPU具备多个内核。这就意味着,多线程程序能够真正地被并行执行,这完全不同于在单核CPU中使用时间共享这种方式。通过在Java中支持函数式编程语法,Lambda表达式能帮助你编写简单的代码去高效地应用这些CPU内核。

  例如,你能够并行地操控大集合对象,通过利用并行编程模式,如过滤、映射和化简(后面将会很快接触到这些模式),就可使用到CPU中所有可用的硬件线程。

  Lambda表达式概览

  在前面提到的使用不同大小写方案查找字符串的例子中,我们想做的就是把方法toLowerCase()的表示法作为第二个参数传入到contains()方法中,为此需要做如下的工作

  1、找到一种途径,可将代码片断当作一个值(某种对象)进行处理

  2、找到一种途径,将上述代码片断传递给一个变量

  换言之,我们需要将一个程序逻辑包装到某个对象中,并且该对象可以被进行传递。为了说的更具体点儿,让我们来看两个基本的Lambda表达式的例子,它们都是可以被现有的Java代码进行替换的。

  过滤

  你想传递的代码片断可能就是过滤器,这是一个很好的示例。例如,假设你正在使用(Java SE 7预览版中的)java.io.FileFilter去确定目录隶属于给定的路径,如清单1所示,

  清单1

  1. File dir = new File("/an/interesting/location/");  
  2. FileFilter directoryFilter = new FileFilter() {  
  3.     public boolean accept(File file) {  
  4.         return file.isDirectory();  
  5.     }  
  6. };  
  7. File[] directories = dir.listFiles(directoryFilter);

  在使用Lambda表达式之后,代码会得到极大的简化,如清单2所示,

  清单2

  1. File dir = new File("/an/interesting/location/");  
  2. FileFilter directoryFilter = (File f) -> f.isDirectory();  
  3. File[] directories = dir.listFiles(directoryFilter);

  赋值表达式的左边会推导出类型(FileFilter),右边则看起来像FileFilter接口中accept()方法的一个缩小版,该方法会接受一个File对象,在判定f.isDirectory()之后返回一个布尔值。

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号