Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
它看起来就像一个工厂的流水线一样,每一步都会对数据进行处理,乍一看好像没区别啊。我们来看看普通的处理和使用Stream处理有什么不一样:
public static void main(String[] args) {
//这是普通的处理
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
//移除为B的元素
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
if(iterator.next().equals("B")) iterator.remove();
}
//这是通过Stream的处理
list = list //链式调用
.stream() //获取流
.filter(e -> !e.equals("B")) //只允许所有不是B的元素通过流水线
.collect(Collectors.toList()); //将流水线中的元素重新收集起来,变回List
System.out.println(list);
}传统方式:
同样是一批数据,直接编写操作对数据处理相当于吧这一批数据处理完之后,又开始下一个步骤继续处理这一批数据,每一步需要等到上一步结束之后,拿到上一批数据才能开始下一步,每一个流程依次进行:

而Stream则是提前编排好流程,每一个元素依次独立走完流水线,无需按批次完成:
(1,2,3) → 1 → 2 → 3 → 合并
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
list.stream()
.map(x -> {
System.out.println("我是第一步: " + x);
return x;
}) //map可以对实现接受一种类型的数据,转为同类型或另一类型的数据
.map(x -> {
System.out.println("我是第二步: " + x);
return x;
})
.forEach(System.out::println);执行结果
我是第一步: 1
我是第二步: 1
1
我是第一步: 2
我是第二步: 2
2
我是第一步: 3
我是第二步: 3
3
我是第一步: 4
我是第二步: 4
4
我是第一步: 5
我是第二步: 5
5
我是第一步: 6
我是第二步: 6
6
实际上,在我们调用Stream的各种方法时,并不是像我们之前那样直接对数据进行处理,而是在进行编排,直到我们调用最后一步forEach或是collect这种收尾的方法时,整个流水线才开始运作(不相信可以试试看去掉最后的收尾操作,不会有任何操作执行)这也是Stream的一种惰性的体现。
注意: 后续我们学习多线程之后,Stream甚至还能利用多线程,同时开展N条流水线进行处理,大大提升数据处理效率。