什么是Streams
这个里面的我们说的Streams是java.util.Streams跟java.io 里面的streams是完全不同的概念。Java 8中的Stream其实是函数式编程里Monad的概念(Monad就是一种设计模式,表示将一个运算过程,通过函数拆解成互相连接的多个步骤,有点链式操作的感觉), 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作 。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。所以说,Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。
Streams特性
- 不是数据结构,没有存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据
- 不修改源数据:它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素
- Stream的操作以Lambda表达式作为参数
- 不支持索引访问,你可以请求第一个数据,但是缺没法访问第二个,第三个
- 很容易生成数组或者List
- 惰性化:所有的intermediate操作都是惰性的,就是说当调用到这些方法的时候并没有开始计算,只有调用到Terminal方法的时候,才会真正开始流的遍历,并且会生成一个结果
- 可以是无限的。 Collection是有限的,但是streams可以是无限的,Short-circuiting操作比如 limit(n) 或者 findFirst()能允许计算无限的streams并在有限的时间内得到结果
如何得到Streams:
- From a Collection via the stream() and parallelStream() methods
- From an array via Arrays.stream(Object[]);
- From static factory methods on the stream classes, such as Stream.of(Object[]), IntStream.range(int, int) or Stream.iterate(Object, UnaryOperator);
- The lines of a file can be obtained from BufferedReader.lines();
- Streams of file paths can be obtained from methods in Files;
- Streams of random numbers can be obtained from Random.ints();
- Numerous other stream-bearing methods in the JDK, including BitSet.stream(), Pattern.splitAsStream(java.lang.CharSequence), and JarFile.stream().
Intermediate 和 Terminal 操作
- Intermediate 操作: map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
- Terminal 操作: forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
- Short-circuiting 操作:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit
PS:Short-circuiting 操作指:对于一个 intermediate 操作,如果它接受的是一个无限大(infinite/unbounded)的 Stream,但返回一个有限的新 Stream。对于一个 terminal 操作,如果它接受的是一个无限大的 Stream,但能在有限的时间计算出结果。
reference:
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
网友评论