正文
代码简洁
,函数式编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环。
多核友好
,Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下parallel()方法。
这一节我们学习stream,也就是Java函数式编程的主角。对于Java 7来说stream完全是个陌生东西,stream并不是某种数据结构,它只是数据源的一种视图。这里的数据源可以是一个数组,Java容器或I/O channel等。正因如此要得到一个stream通常不会手动创建,而是调用对应的工具方法,比如:
常见的stream接口继承关系如图:
图中4种stream接口继承自BaseStream,其中IntStream, LongStream, DoubleStream对应三种基本类型(int, long, double,注意不是包装类型),Stream对应所有剩余类型的stream视图。为不同数据类型设置不同stream接口,可以1.提高性能,2.增加特定接口函数。
你可能会奇怪为什么不把IntStream等设计成Stream的子接口?毕竟这接口中的方法名大部分是一样的。答案是这些方法的名字虽然相同,但是返回类型不同,如果设计成父子接口关系,这些方法将不能共存,因为Java不允许只有返回类型不同的方法重载。
虽然大部分情况下stream是容器调用Collection.stream()方法得到的,但stream和collections有以下不同:
-
无存储
。stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
-
为函数式编程而生
。对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。
-
惰式执行
。stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
-
可消费性
。stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
对stream的操作分为为两类,
中间操作(intermediate operations)和结束操作(terminal operations)
,二者特点是: