距明年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年一季度发布。