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

Lambda表达式是自Java SE 5引入泛型以来最重大的Java语言新特性,本文是2012年度最后一期Java Magazine中的一篇文章,它介绍了Lamdba的设计初衷,应用场景与基本语法。(2013.01.07最后更新)

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

File dir = new File("/an/interesting/location/");
FileFilter directoryFilter = new FileFilter() {
    public boolean accept(File file) {
        return file.isDirectory();
    }
};
File[] directories = dir.listFiles(directoryFilter);

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

清单2

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

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

实际上,由于Lambda表达式利用了类型推导,基于后面的工作原理,我们还可以进一步简化上述代码。编译器知道FileFilter只有唯一的方法accept(),所以它必定是该方法的实现。我们还知,accept()方法只需要一个File类型的参数。因此,f必定是File类型的。如清单3所示,

清单3

File dir = new File("/an/interesting/location/");

File[] directories = dir.listFiles(f -> f.isDirectory());

你可以看到,使用Lambda表达式会大幅降低模板代码的数量。

一旦你习惯于使用Lambda表达式,它会使逻辑流程变得非常易于阅读。在达到这一目的的关键方法之一就是将过滤逻辑置于使用该逻辑的方法的侧边。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索file
, 方法
, 代码
, lambda
, java中 file使用
, 表达式
, lambda 表达式
, 线程lambda
, 一个
, lambda表达式
FileFilter
lambda表达式、c lambda表达式、python lambda表达式、java lambda表达式、java8 lambda表达式,以便于您获取更多的相关知识。

时间: 2024-10-01 02:57:49

探索Java语言与JVM中的Lambda表达式的相关文章

在Java中使用Lambda表达式的技巧

在本文中,我们将展示一些在 Java 8 中不太为人所了解的 Lambda 表达式技巧及其使用限制.本文的主要的受众是 Java 开发人员,研究人员以及工具库的编写人员. 这里我们只会使用没有 com.sun 或其他内部类的公共 Java API,如此代码就可以在不同的 JVM 实现之间进行移植. 快速介绍 Lambda 表达式作为在 Java 8 中实现匿名方法的一种途径而被引入,可以在某些场景中作为匿名类的替代方案. 在字节码的层面上来看,Lambda 表达式被替换成了 invokedyna

深入理解Java中的Lambda表达式_java

 Java 8 开始出现,带来一个全新特性:使用 Lambda 表达式 (JSR-335) 进行函数式编程.今天我们要讨论的是 Lambda 的其中一部分:虚拟扩展方法,也叫做公共辩护(defender)方法.该特性可以让你在接口定义中提供方法的默认实现.例如你可以为已有的接口(如 List 和 Map)声明一个方法定义,这样其他开发者就无需重新实现这些方法,有点像抽象类,但实际却是接口.当然,Java 8 理论上还是兼容已有的库. 虚拟扩展方法为 Java 带来了多重继承的特性,尽管该团队声称

mysql 编码 汉字识别-用Java语言连接wampserver中mysql数据库时,遇到问题,请看内容。

问题描述 用Java语言连接wampserver中mysql数据库时,遇到问题,请看内容. 用Java语言连接wampserver集成中的mysql,当用java代码往mysql数据库插入数据后,代码中的中文字符在数据库中变成了"?",但是使用mysql客户端.http:// localhost/phpmyadmin/ 页面 插入中文时,就没有这种情况发生,请指点. 解决方案 参考 mysql/java charset issue 在连接字符串指定字符集,比如jdbc:mysql://

用java语言将Excel中的数据导入到SqlServer2000中

问题描述 怎样用java语言将Excel中的数据导入到SqlServer2000中? 解决方案 解决方案二:sqlserver本身就支持导入excel数据解决方案三:需要借助POI

C++中的Lambda表达式详解_C 语言

我是搞C++的 一直都在提醒自己,我是搞C++的:但是当C++11出来这么长时间了,我却没有跟着队伍走,发现很对不起自己的身份,也还好,发现自己也有段时间没有写C++代码了.今天看到了C++中的Lambda表达式,虽然用过C#的,但是C++的,一直没有用,也不知道怎么用,就可怜的连Lambda语法都看不懂.好了,这里就对C++中的Lambda进行一个简单的总结,就算是对自己的一个交代,我是搞C++的,我是一个C++ programmer. 一段简单的Code 我也不是文艺的人,对于Lambda的

Android Studio中引入Lambda表达式的方法

本文介绍的是在Android Studio中引入Lambda表达式的方法,下面话不多说,来看看详细的介绍. 方法如下: 依次点击 [File][Other Settings][Default Project Structure]确保当前项目使用的JDK版本是1.8. 打开项目(Project)的build.gradle,在dependencies节点添加 classpath 'me.tatarka:gradle-retrolambda:3.2.0' 打开项目(Module)的build.grad

Android Studio中使用lambda表达式的方法

1.module的build.gradle里buildTypes中添加: compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } 2.module的build.gradle里defaultConfig中添加: jackOptions.enabled = true 3.注意事项:jack可能会导致中文乱码,所以需要在gradle.proper

快速入门Java中的Lambda表达式_java

Lambda简介 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块). Lambda表达式还增强了集合库. Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及 java.util.stream 包. 流(stream)就如同迭代器(iterator),但附加了许多

一个Java 8中简单Lambda表达式程序

原文链接 作者:   Mohamed Sanaulla  译者: 李璟(jlee381344197@gmail.com) 我尝试过把Lambda表达式融入到我的代码中,下面的代码例子是此次尝试的结果.对于那些完全不知道Lambda表达式的Java程序员,我强烈建议在继续阅读之前,浏览一下这篇文章. Ok,现在你已经熟悉Lambda表达式了(在阅读过推荐的Lambda入门文章之后),那我们现在开始学习一个我认为很好的Lambda表达式的例子. 考虑一下这种场景:某些操作在执行之前需要做预处理,执行