距明年 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 )关注我们,并与我们的编辑和其他读者朋友交流。
评论