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

lambdas for_Lambdas:来到您附近的Java 8!相关推荐

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

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

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

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

  3. java多线程 异常处理_Java8多线程ForkJoinPool:处理异常

    java多线程 异常处理 引入Java8 lambda背后的主要动机之一是能够尽可能轻松地使用多核的能力(请参阅精通Lambdas:多核世界中的Java编程 ). 只需将代码从collection.s ...

  4. Java 8最新消息

    Java 8的开发再次开始主导新闻. 最近的帖子涵盖了扩展JDK 8的Milestone 7以确保其功能完整,Java 8中现在可用的Date / Time API以及对Java教程的更新以涵盖一些J ...

  5. Java死了还是无敌?

    作家艾萨克·阿西莫夫(Isaac Asimov)曾经说过"唯一不变的就是变化". 这不仅仅是软件行业中的一个短语,这是绝对的事实. 曾经有一天,Corba为王,但Web Servi ...

  6. java slf4j日志级别_java - 在slf4j中设置运行时消息的日志级别 - 堆栈内存溢出

    ===============>>#1 票数:41 已采纳 使用slf4j无法做到这slf4j . 我想,缺少这个功能的原因是,几乎不可能为slf4j构建一个Level类型,它可以有效地映 ...

  7. java 最佳主键_最佳Java 8书籍

    java 最佳主键 Today we will look into the best java 8 books. Java SE 8 is one of the major releases in r ...

  8. 小饶学编程之JAVA SE第二部分——Web 前端基础:09CSS3

    CSS3 一.CSS简介 二.入门 三.CSS的分类 四.选择器 4.1 基本选择器 4.2 层次选择器 4.3 结构伪类选择器 4.4 属性选择器 4.5 优先级 五. 元素的分类 六.常用样式 6 ...

  9. 深圳Java学习:Java中的原子操作

    深圳Java学习:Java中的原子操作 来到千锋学习Java已经有一段时间了,由当初的懵逼状态逐渐好转,也逐渐养成了写技术学习笔记的习惯,今天总结了一下Java中的原子操作. 1.Java中的原子操作 ...

最新文章

  1. python提交spark_带有python入口点的sparksubmit
  2. asp向不同的用户发送信息_ASP.NET Core 中的那些认证中间件及一些重要知识点
  3. 使用AI进行人脸检测
  4. vsftp虚拟用户权限问题
  5. 截取数组中的第i个元素,并返回截取后的结果
  6. Https背景与证书在spring boot项目中的使用
  7. java-第五章-while=计算1~50中是7的被耍的数值之和
  8. linux中rlwrap安装
  9. 我是一只幼鸟,望着那蓝蓝的天空时不时就想翱翔起来
  10. 解决AndroidStudio Locat侧边栏消失
  11. vue 使用 createjs 绘制扇形
  12. 股票重大利好开盘封涨停买不到?试试这个办法
  13. iOS程序猿的flutter学习之路
  14. spack Bootstrapping Mirrors
  15. java word 添加水印图片_Java添加Word文本水印和图片水印
  16. 代码改变生活-文件重命名
  17. 下载python安装包--国内环境快速下载
  18. cocos2d-html5 游戏实战源代码大集合和下载(包括flappy,popstar等----持续更新中----)...
  19. 关于onenote右键图片快速裁剪
  20. LC低通滤波器的截止频率与LC谐振频率的关系

热门文章

  1. SpringCloud Gateway配置自定义路由404坑
  2. mybatis源码阅读(七) ---ResultSetHandler了解一下
  3. JavaScript学习总结(一)——JavaScript基础
  4. XML解析(二),DOM解析XML
  5. java 中 image 和 byte[] 相互转换
  6. Oracle入门(十四B)之PL/SQL异常处理
  7. android 处理http状态码,OkHttp(Retrofit)对于http状态码202的处理
  8. 用python进行自然语言处理_Python自然语言处理示例:SVM和贝叶斯分类
  9. 在win10系统中安装Visual C++ 6.0的具体方法
  10. spring(2)装配Bean