简介
Stream represents a sequence of objects from a source, which supports aggregate operations. Following are the characteristics of a Stream −
- Sequence of elements − A stream provides a set of elements of specific type in a sequential manner. A stream gets/computes elements on demand. It never stores the elements.
- Source − Stream takes Collections, Arrays, or I/O resources as input source.
- Aggregate operations − Stream supports aggregate operations like filter, map, limit, reduce, find, match, and so on.
- Pipelining − Most of the stream operations return stream itself so that their result can be pipelined. These operations are called intermediate operations and their function is to take input, process them, and return output to the target. collect() method is a terminal operation which is normally present at the end of the pipelining operation to mark the end of the stream.
- Automatic iterations − Stream operations do the iterations internally over the source elements provided, in contrast to Collections where explicit iteration is required.
(译文)Stream为输入源提供了对象序列,它支持聚合操作。以下是Stream的特性:
- 元素序列——元素是特定类型的对象,Stream按需获取/计算元素,它不存储元素;
- 数据源——Stream将集合、数组或输入输出资源作为输入源;
- 聚合操作——Stream支持filter、map、limit、reduce、find、match等聚合操作;
- Pipelining——大多Stream操作返回Stream本身,这样多个操作可以串联成一个管道,如同流式风格。这些操作被称为中间操作,这些方法获取输入、进行处理、然后将输出返回给目标。collect()方法是最终操作,一般在流水线的末尾出现标志着Stream的结束;(类似的最终操作还有:forEach、reduce)
- 内部迭代——与需要显式迭代的集合相比,流操作在内部对提供的源元素执行迭代(通过访问者模式完成)。
说明
Stream是Java8引入的一个抽象层,使用它可以用类似于SQL语句声明式地处理数据。比如可以看下方sql语句。
SELECT max(salary), employee_id, employee_name FROM Employee
上面的sql语句在用户端并没有执行任何计算操作的情况下,自动返回了Employee表中salary的最大值max(salay)。但如果使用Java的集合类,开发者须使用循环并且要多次比对才能给出最大值。另一个需要考虑的就是效率问题,由于现在大多都是多核处理器,Java开发人员用并行代码来处理时容易出错。
为了解决上述问题,Java8引入了Stream概念,它让开发人员可以声明式地处理数据并且可以在不写任何特定代码的情况下利用多核处理器。
形象化展示
1 | +--------------------+ +------+ +------+ +---+ +-------+ |
用Java表示上述流程
1 | // 这里widgets为输入源 |
生成流
在Java8中, 集合接口有两个方法来生成流:
- stream() − 为集合创建串行流。
- parallelStream() − 为集合创建并行流。
举例如下:
1 | public class GenerateStream { |
输出
1 | abc |
Steam常用方法
| 方法名 | 功能 |
|---|---|
| collect | 利用Collectors接口实现归约操作 |
| filter | 通过设置条件过滤出元素 |
| forEach | 迭代流中的每个数据 |
| limit | 获取指定数量的流 |
| map | 映射每个元素到对应的结果 |
| sorted | 对流进行排序 |
Stream完整示例
1 | import java.util.*; |
Java7和Java8输出对比
| Java7 | Java8 |
|---|---|
| 列表: [abc, , bc, efg, abcd, , jkl] | 列表: [abc, , bc, efg, abcd, , jkl] |
| 空字符数量为: 2 | 空字符串数量为: 2 |
| 字符串长度为 3 的数量为: 3 | 字符串长度为 3 的数量为: 3 |
| 筛选后的列表: [abc, bc, efg, abcd, jkl] | 筛选后的列表: [abc, bc, efg, abcd, jkl] |
| 合并字符串: abc, bc, efg, abcd, jkl | 合并字符串: abc, bc, efg, abcd, jkl |
| 平方数列表: [9, 4, 49, 25] | 平方数列表: [9, 4, 49, 25] |
| 列表: [1, 2, 13, 4, 15, 6, 17, 8, 19] | 列表: [1, 2, 13, 4, 15, 6, 17, 8, 19] |
| 列表中最大的数 : 19 | 列表中最大的数 : 19 |
| 列表中最小的数 : 1 | 列表中最小的数 : 1 |
| 所有数之和 : 85 | 所有数之和 : 85 |
| 平均数 : 9.444444444444445 | 平均数 : 9.444444444444445 |
| 随机数: | 随机数: |
| 1284026997 | -1374685114 |
| -1178762425 | -1033099952 |
| -1879259729 | -885959722 |
| -29731464 | -401309484 |
| 1555365798 | 111924303 |
| -1011945483 | 124136966 |
| 235379193 | 1033295745 |
| -1233162879 | 1297745871 |
| -704470337 | 1322164906 |
| 1219156879 | 2111470129 |
从上表可以看出Java8输出结果与Java7结果相同,但使用新特性的Java8的代码更加简洁明了!
更多详细内容参见官方文档