Lambda 表达式现状分析

阅读数:1745 2013 年 1 月 22 日

话题:Java语言 & 开发

距明年 Java 8 发布还有不到一年时间,Brian Goetz 发布了最新的Lambda 表达式现状分析,涵盖了 Java 集合 API 的改进 。Java 8 最受期待的特性之一是引入了Lambda 表达式,Java 集合 API 对它的重点支持是确保该类库被广泛使用的关键所在。如果你不熟悉 Lambda 表达式的语法,请查看先前的一篇文章Lambda 表达式现状分析以及之前 InfoQ 的相关报道,以便了解该语法的详细内容。

因为替换整个集合库不现实,所以有必要扩展该库以支持 Lambda 表达式。与现如今用的外部实现(例如迭代器和枚举)截然相反,该计划打算使用内部迭代器(也就是,在集合中将 Lambda 表达式传递给 forEach)。新添加的接口 Stream 将支持值序列,以及 stream() 之类的方法将集合转换为 Stream。

Stream 和普通的集合不同,它不需要存储空间(所以可以是无限大或按需读取),它实际上是以函数方式处理,并且能够延迟生成。例如,我们可以创建一个代表素数的 Stream,让每个新元素产生序列中的下一个素数。

Stream 接口还将提供大量的函数处理方法,包括 forEach()、filter()、fold()、anyMatch()、map() 以及 flatMap()。该接口能以适当的方式构造集合所使用的具体类型,或为了其他类参与,它以通用方式实现。延迟意味着使用类似 findFirst 之类的方法,可以使用、过滤、匹配 Stream。当找到第一个匹配元素时,这会被触发并立即停止,无需遍历整个集合。集合现状分析一文中有个类似的例子:

Optional<Shape> firstBlue =
 shapes.stream()
  .filter(s -> s.getColor() == BLUE)
  .findFirst();

java.util.function 包将提供入门级别的函数接口,例如 Predicate、Function、UnaryOperator 以及 BinaryOperator,该理念是为了让开发者还能够添加自定义的函数接口类型。该函数包还引入了新类型 Optional,它提供了表示潜在 null 值的机制。该包装类要么保存类的单例,要么以对象安全的方式表示 null 值。正如上个月一个细长的邮件线索中讨论的那样,并不是所有人都满意这个设计。其他语言,例如 Scala 和 Haskell,提供了更多的 Monad 方式的 Optional 的函数视图。但 Brian Goetz,“如果有人对我们没将 Java 变成 Scala 或者 Haskell 感到不爽,那么抱歉,我们没有这么做。”,他还“少数人其实很容易就能冒充社区的声音”。与此同时一些强类型以及小众语言在函数设计上将更进一步,数以万计的 Java 开发者鲜有熟悉函数式编程,为最多数开发者谋求利益最大化是 Oracle 的首要目标。

在 Java 语言中加入 Stream 和函数还可让操作并行执行。假设给定数据的逻辑 Stream,结果可分割成不同级别的数据块,然后交给 fork/join 之类的并行处理架构。当前的提案引入了 Spliterator,它可将大数据块分割成更小的适合并行处理的数据块。通过暴露分割数据结构为更小单元的一般性方法,在允许 fork/join 框架操作通用数据集合的同时,数据结构能够提供数据的有效部分。

最后,似乎人们对 Lambda 表达式的热爱正在往 EL(表达式语言)中渗透,它是 Java EE 的一部分。先前有 LINQ 这样执行数据处理的概念,但随着即将到来的 Lambda 表达式支持,EL决定应该接纳某些 Lambda 表达式语法,以便更大程度兼容 Java 语言。这将推迟 EL 项目的设计完成时间至今年年底,最终将于 2013 年一季度发布。

查看英文原文State of the Lambda


感谢贾国清对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。