lambdas for_Lambdas:来到您附近的Java 8!

lambdas for

什么是Lambda?

Lambda表达式是一种匿名函数,可以在方法中内联编写,并且可以在使用表达式的任何地方使用。 有时您可能会发现它们被称为闭包,尽管我在下面解释了对该参考的一些注意事项。 像普通的Java方法一样,它具有参数和可以执行的主体。 Java 8中令人兴奋的新功能之一是lambda表达式,该表达式已定义为JSR 335的一部分。

添加lambda表达式将使Java更轻松地支持函数式编程技术和高阶函数。 这并不是说突然变成一夜之间成为诸如Haskell之类的奇特而深奥的语言,但是它将朝着与诸如C#,Ruby或python之类的语言一样的方向发展。 也就是说,为有意义的功能样式提供部分支持,但仍允许您使用命令式技术,例如可变变量。

基本语法

这是一个lambda表达式,该表达式使数字递增1:

x -> x + 1

如您所见,表达式以参数开头,以参数主体结尾,并用箭头将两者分开。 您也可以显式键入参数,在参数上放置类型注释或具有多个参数。 如果您想执行这些操作,则需要将参数放在方括号中,例如:

// Explicit Types(Integer x) -> x + 1// Multiple Arguments(Integer x1, Integer x2) -> x1 + 1// Annotations:(Integer x1, @SuppressWarnings("unused") Integer x2) -> x1 + 1

到目前为止,所有的lambda主体都是表达式,但是您也可以像常规方法一样,将主体编写为一系列语句。

(x) -> { x += 5; System.out.println(x); return x; 
};

由于lambda是正则表达式,因此您可以将其视为正则表达式。 例如,您可以将它们分配给变量,将它们作为参数传递给其他方法。

// a method: 
public static void useFunc(IntFun f) { System.out.println(f.apply(2)); 
} // in code 
IntFun inc = x -> x + 1; 
useFunc(inc); 
useFunc(x -> x + 1);

类型?

由于这是Java,因此即使不是所有这些“ x”参数都标记为“整数”,所有这些函数仍然是静态类型的。 幸运的是,Java 7中方法句柄的引入提供了一种引用方法本身的方法。 这意味着您的函数并不需要全部实现某个通用接口,它们可以是被认为是“函数接口”的任何东西。

引用规范草案,“功能接口是仅具有一种抽象方法的接口,因此表示单个功能协定。” 这些也可以用首字母缩写词“ SAM”来表示,它代表“单一抽象方法”。 例如:

interface Runnable { void run(); } interface Function { public R apply(A a); } interface IntFun extends Function {} // equals is defined by java.lang.Object, so this only has one abstract method 
interface Comparator { boolean equals(Object obj); int compare(T o1, T o2); 
}

因此,通过确保使用保持这些约束的接口,当前正在编写/正在编写的任何API都可以被lambda使用。 Guava库是一个已经鼓励有限的功能编程风格的示例API。

更有趣的例子

经验丰富的函数式程序员会意识到map函数,该函数会为您返回一个新列表,其中每个值都由函数更改。 在番石榴世界中,此功能称为“变换”。 这是您今天可以编写的一些Java代码示例,使用它来递增列表:

Collection result = transform(newArrayList(1, 2, 3), new Function() { @Override public Integer apply(Integer x) { return x + 1; } 
});

这是一个高阶函数的示例,即以函数为参数或返回函数的函数。 转换函数使迭代集合和构建新集合的过程抽象化,从而可以编写更多抽象的高级代码。 不幸的是,由于我们受到了很多行噪声的干扰,因此在一定程度上克服了可读性的优势,但是如果您使用lambda重写它:

Collection result = transform(newArrayList(1, 2, 3),x -> x + 1);

另一个常用的高阶函数是滤波函数。 如果为它提供一个集合和一个谓词,它将返回一个新集合,其中包含该谓词对其适用的旧集合中的元素。 这是一个以匿名内部类样式和lambda表达式方式编写的代码示例。

Collection threeAndFive = filter(newArrayList(1, 3, 5), new Predicate() { @Override public boolean apply(Integer x) { return x > 2; } 
}); Collection threeAndFiveByLambda = filter(newArrayList(1, 3, 5),x -> x > 2);

方法参考

当然,您可能已有一个已经定义了许多方法的现有代码库,您希望使用它们代替lambda。 目前,这在Java中也可以使用匿名内部类实现,但同样麻烦。 除了提供lambda表达式外,JSR 335还提出了一些语法糖,以使此过程更容易。 您可以使用'::'符号作为已编写的现有方法的方法参考。 这是前面的示例,但是使用了方法参考:

// Existing method 
public static boolean greaterThanTwo(Integer x) { return x > 2; 
} // prints [3, 5] 
System.out.println(filter(newArrayList(1,3,5),LambdasExample::greaterThanTwo));

他们真的是闭包吗?

在引言中,我提到过lambda表达式可以称为closures 。 这意味着一个函数能够引用其正常范围之外的变量,或者被封闭在周围范围的自由变量之上。

int value = 5; IntFun addValue = x -> x + value;

在此代码示例中,“ addValue”功能能够引用周围范围中的名为“ value”的变量,尽管对此有一些警告。 如果您之前编写过匿名内部类,那么您会回想起它们只能引用周围的变量,这些变量被标记为final,即未分配给它们。 这里的限制是相似的,只是它已被概括为最终有效的限制 。 简而言之,您可以引用未分配给多个变量的变量。 原理是,如果变量被标记为final或可以被标记为final而不引入编译器错误,则该变量实际上是final。

尝试和链接

lambdas规范的早期草案审核的一部分已经在线发布,并且如果您想了解正在发生的事情的来龙去脉,那么这可能对您来说很有趣。 如果您有兴趣尝试编写一些lambda代码,则已经有二进制快照 。 这些内容经常更新,如果您想了解lambda内部结构的实质,可以尝试构建源代码 。 关于使用二进制代码编写代码的唯一警告是,由于它仍处于草稿版本中,并且仍在使用“#”运算符而不是“ ::”作为方法参考语法,因此仍然存在一些bug。

摘要

这是对Java 8的Lambda表达式的某些概念的介绍,因此简化了所涉及的一些问题,但对于读者来说,了解即将发生的事情应该足够了。 很高兴看到Oracle在事物的语言方面引入了一些有用的更改,这种更改已经停滞了一段时间。

参考: Lambdas:来到您附近的Java 8! 从我们的JCG合作伙伴 Richard Warburton在Insightful Logic博客中获得。

翻译自: https://www.javacodegeeks.com/2013/07/lambdas-coming-to-a-java-8-near-you.html

lambdas for

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python反转一个整数、123变成321_python整数反转算法

题目描述:给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。示例 1:输入: 123输出: 321示例 2:输入: -123输出: -321示例 3:输入: 120输出: 21注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231…

GSM网络与CDMA网络话务量、基站容量相关计算

GSM网络与CDMA网络的区别 网络类型GSMCDMA编码方式频分多址和时分多址相结合方式码分多址覆盖面积较小较大容量小大话音质量较低支持软切换,和较软切换,使得用户在基站边缘通话时信号更加稳定 GSM规范中推荐使用的频道配置规范 GSM的频道配置 每个小区…

python开源流程图软件_Dia

软件简介Dia是开放源码的流程图软件,是GNU计划的一部分,程式创立者 是Alexander Larsson。Dia使用single documentinterface (CSDI)模式,类似于GIMP。Dia将多种需求以模组化来设计,如流程图、网络图、电路图等。各模组之间的符号仍…

Spring,Reactor和ElasticSearch:使用伪造的测试数据进行标记

在上一篇文章中,我们创建了一个从ElasticSearch的API到Reactor的Mono的简单适配器,如下所示: import reactor.core.publisher.Mono;private Mono indexDoc(Doc doc) {//... }现在,我们希望以受控的并发级别运行此方法数百万次。 …

通信工程施工图案例分析

分析入口 给你一个城市,要如何开始分析,如下图: 分析一下城市的情况: 主要有: 行政区域地理位置,周围的地形经济发展情况X事发展的情况交通发展的情况其他:还包括农林、旅游、气象、地质、水…

参数整定临界比例度实验_PID理解起来很难?系统讲解PID控制及参数调节,理论加实际才好!...

在实际工程中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。PID控制器问世至今以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。PID调节控制是一个传统控制方法,它适…

工程计价里面的表以及相关税额的计算

序号表名表一工程预算总表表二建筑安装工程费用预算表表三(甲)建筑安装工程量算表表三(乙)建筑安装工程施工机械使用费算表表三(丙)建筑安装工程仪器仪表使用费预算表表四(甲)国内器…

apache jmeter_Apache Server和JMeter调试

apache jmeter我一直在使用JMeter为生产服务器生成负载以测试我的应用程序。 该测试计划具有13个以上的HTTP采样器以发出不同的请求,并具有一个正则表达式提取器以从响应中提取一些值。 此值在连续的HTTP Sampler中使用。 这个测试用例简单而直接。 最初&#xff0c…

CDMA系统的三种码

CDMA系统中用到的三种码:PN码、Wash码、长码 种类作用PN码伪随机码,主要是把发送的序列转化为伪随机序列Wash码消除或者抑制多址干扰,如果多址信号是正交的,那么多址干扰可以减小到0;区分前向信道长码区分用户的业务信…

4计算准确率_孩子计算总出错?4个好方法帮助低年级学生提高计算准确率!

低年级孩子,由于活泼好动,注意力不容易集中,思维容易被分散。表现在学业上,就会出现学习水平参差不齐的情况。而最主要的表现,就是计算能力的差异。据资深数学老师观察:成绩好的孩子,一般不只掌…

使用Speedion 3.0.17或更高版本轻松从事务中返回值

交易次数 在我以前的文章中,我写了关于如何使用Speedment轻松使用事务的方法,其中我们原子地更新了两个银行帐户。 众所周知,事务是一种将多个数据库操作组合到一个原子执行的单个操作中的方法。 但是事务不仅与更新数据库有关,而…

无线业务需求的线路设计以及拓扑图实现

MSC →\rightarrow→BSC →\rightarrow→ BTS ADM-1 →\rightarrow→ ADM-14 →\rightarrow→ ADM-16 边缘层 →\rightarrow→ 汇聚层 →\rightarrow→ 核心层 设计光缆链路时要注意的问题: 链路要适当长一些,减少中继设备接续造成的损耗尽可能多的使…

双代号网络图节点时间参数_管理和实务都考!快速学会单代号与双代号参数计算...

工程网络计划是二级建造师《建设工程施工管理》科目每年均会进行考核的高频考点,重点在双代号、单代号网络计划的概念及应用。主要题型为通过网络图或文字描述计算相关网络参数或确定关键线路,本篇就双代号、单代号网络计划相关参数的计算,以…

idea中maven执行install报错_IntelliJ IDEA Maven编译install时报错,无效的发行版:1.8

1.首先看java环境是否配置正确JAVA_HOME : C:\Program Files\Java\jdk1.8.0_92 //安装的Jdk路径PATH: %JAVA_HOME%\bin;按下"window"R 输入cmd 按下"ENTER" 输入java -version,如果出现了版本号等信息说明配置成功2.确认maven配…

gc可视化分析_GC内存可视化器教程–第一部分

gc可视化分析正如您从过去的文章中可能已经读到的那样,要获得的Java程序员的一项关键技能就是理解和评估JVM的运行状况的能力,例如Java堆内存占用量以及垃圾回收过程。 为了实现上述目标,所有JVM供应商(Oracle,IBM等&…

涉及到IP地址的各种计算(CIDR/子网划分/IP地址范围的确定等)

1.判断是否属于子网 方法:如子网86.32.0.0/12,它的网络前缀有12位,把点十分制划为二进制展开,每一个点分隔开的是相邻的两组数字,每组数字有八个,你把他写在纸上数一下,扣掉前面的八位数字&…

go 变量大写_go语言如何将大写转小写

go语言将大写转小写的方法:首先创建一个go示例文件;然后定义一个字符串类型的变量;接着使用ToLower函数将大写的变量字符全部转成小写;最后使用print函数打印转换后的结果即可。本文操作环境:Windows7系统、Go1.11.2版…

为什么Spring的健康状况会再次下降,下降,上升,上升,上升和下降?

为什么 我们新JavaScript客户端应用程序会定期调用Grails后端的/health端点来确定离线状态。 事情开始变得“​​有趣”。 我们免费获得此端点,因为Grails基于Spring Boot,而Spring Boot带有一个名为Spring Boot Actuator的子项目。 这给了我们许多端点…

浅谈auto与decltype函数的区别

auto与decltype都是C里处理类型的指示符,它们的使用场景如下: autodecltype在我们需要给变量赋值的时候,简单的程序往往可以通过观察得出表达式的类型,但在一些大型程序中这样做往往是行不通的,为此可以使用auto指示符…

php mysql 快餐_用PHP+MYSQL做一个简单的点餐系统的后台,初学者. 请高手指点下如何实现后台添加菜名 餐馆 价格...

展开全部" name"cm" placeholder"菜名" type"text" />" name"cg" placeholder"餐馆" type"text" />" name"jg" placeholder"价格" type"text" />if…