什么是Lambda?

Lambda表达式是一种匿名函数,可以在方法中内联编写,并且可以在使用表达式的任何地方使用。 有时您可能会发现它们被称为闭包,尽管我在下面解释了对该参考的一些注意事项。 像普通的Java方法一样,它具有参数和可以执行的主体。 lambda表达式是Java 8中令人兴奋的新功能之一,它已定义为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:来到您附近的Java 8!相关推荐

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

    lambdas for 什么是Lambda? Lambda表达式是一种匿名函数,可以在方法中内联编写,并且可以在使用表达式的任何地方使用. 有时您可能会发现它们被称为闭包,尽管我在下面解释了对该参考的 ...

  2. Wordcounter,使用Lambdas和Fork / Join计算Java中的单词数

    这些天来,我发布了Wordcounter ,这是一个Java库和命令行实用程序,用于对文本文件中的单词进行计数并对单词计数进行分析,从而大量使用了功能编程结构和并行计算方法. 这是我在"令人 ...

  3. lambdas for_Wordcounter,使用Lambdas和Fork / Join计算Java中的单词数

    lambdas for 这些天来,我发布了Wordcounter ,这是一个Java库和命令行实用程序,用于对文本文件中的单词进行计数并对单词计数进行分析,从而大量使用了功能编程结构和并行计算方法. ...

  4. java 反向映射,如何使用lambdas實現反向映射Java?

    在這個例子中,我將這個列表累加到LinkedList. LinkedList實現了Deque(雙端隊列),它允許我以後進先出(LIFO)順序追加項目. 我使用LinkedList :: addFirs ...

  5. Java Lambdas简介

    Java 8的主题是lambdas. 我已经注意到,对于许多Java程序员来说,lambda都是非常难的材料. 因此,让我们尝试对它们有一个基本的了解. 首先,lambda到底是什么? Lambda是 ...

  6. JAVA 8:Lambdas表达式初体验

    原文链接,译文链接,译者:郑旭东 Lambdas项目是即将发布(译者注:原作者写本文的时候JAVA8尚未发布)的JAVA8中重要主题,同时它应该也是众多JAVA开发者最期待的功能.还有一个非常有意思的 ...

  7. 是否可以将Java 8用于Android开发?

    本文翻译自:Is it possible to use Java 8 for Android development? Searching the web, it is not clear if Ja ...

  8. 这个类库可以帮助你理解Java中的函数式编程

    每当JDK发布了新版本就有同学说"你发任你发,我用Java 8",可在工作中有不少人依然不太擅长使用Java8的新特性,而这些特性往往让Java不再"臃肿".不 ...

  9. lambda java_Java Lambdas简介

    lambda java Java 8的主题是lambdas. 我已经注意到,对于许多Java程序员来说,lambda都是非常难的材料. 因此,让我们尝试对它们有一个基本的了解. 首先,lambda到底 ...

最新文章

  1. java程序的装载与检查_浅谈Java类型装载、连接与初始化
  2. 运行时常量池在哪里_C++干货系列——从编译期常量谈到constexpr(一)
  3. 单个接口添加超时时间_SpringBoot使用Guava令牌桶对接口限流
  4. “学霸”是怎样炼成的?
  5. 在Spring MVC应用程序中使用Bean Validation 1.1获得更好的错误消息
  6. flask框架基本使用(2)(响应与重定向)
  7. VS2010与.NET4系列 10. VS2010代码智能感知增强
  8. 【备份】golang开发环境搭建
  9. ajajx请求php能设置cookie,为什么在AJAX请求返回后浏览器没有设置cookie?
  10. 《室内设计软件Sketch Up零初级入门视频教程》
  11. 计算机基础知识试题和答案
  12. HTML中font标签用法
  13. 交换机基本原理以及配置
  14. ffmpeg 视频转码
  15. 明日复明日,明日何其多,我生待明日,万事成蹉跎(分享)
  16. CSS 网格 Gird 布局
  17. 手把手教你写专利申请书/如何申请专利
  18. 股票实时数据接口软件的数据来源是哪里?
  19. ata职业技能评价证书考出来有啥用?
  20. 关于 simulink 的 1/z 模块是什么的问题

热门文章

  1. mysql 时间 1_(转)mysql日期时间函数1
  2. 使用互联网了解的两个月里_我两个月来对Quarkus的了解
  3. java –cp ./:_成为Java流大师–第3部分:终端操作
  4. java 反射api_反射是最重要的Java API
  5. java私有属性和私有方法_Java接口–历年来Java 9之旅–默认方法和私有方法
  6. javaserver_什么是JavaServer Faces(JSF)–(第2部分)
  7. 扩展 junit 框架_JUnit 5 –扩展模型
  8. 众神进入瓦尔哈拉_一时冲动:“通往瓦尔哈拉之路的冒险”
  9. spark 流式计算_流式传输大数据:Storm,Spark和Samza
  10. java.lang.Record:规范草案