Stream流和I/O流其实没有太大的关系,在Java 8中,得益于Lambda所带 来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端。Stream(流)是一个来自数据源的元素队列,元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。数据源:流的来源,可以是集合,数组 等。

这张图中展示了过滤、映射、跳过、计数等多步操作,这是一种集合元素的处理方案,而方案就是一种“函数模型”。图中的每一个方框都是一个“流”,调用指定的方法,可以从一个流模型转换为另一个流模型。而最右侧的数字3是最终结果。这里的 filter 、 map 、 skip 都是在对函数模型进行操作,集合元素并没有真正被处理。只有当终结方法 count执行的时候,整个模型才会按照指定策略执行操作。而这得益于Lambda的延迟执行特性。
在使用for循环遍历一个集合或者数组的时候,for循环的语法是“怎么做”,其方法体才是“怎么做”。遍历是指每一个元素逐一进行处理,而并不是从第一个到最后一个顺次处理的循环,前者是目的,后者是方式。
下面通过一个例子来对比以下传统的for循环遍历集合和使用stream流来遍历集合:
package com.wjh.util;import java.util.ArrayList;import java.util.List;/*** @author 26913*/public class TestMain {public static void main(String[] args){List<String> list = new ArrayList<>();list.add("张无忌");list.add("周芷若");list.add("赵敏");list.add("张强");list.add("张三丰");//对list集合中的元素进行过滤,只要以张开头的元素,存储到一个新的集合中List<String> listA = new ArrayList<>();for (String s : list) {if (s.startsWith("张")) {listA.add(s);}}//对listA集合进行过滤,只要姓名长度为3的人,存储到一个新集合中List<String> listB = new ArrayList<>();for (String s : listA) {if (s.length() == 3) {listB.add(s);}}//遍历listB集合for (String s : listB) {System.out.println(s);}}}
运行结果:
每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。循环是做事情的方式,而不是目的。另一方面,使用线性循环就意味着只能遍历一次,如果希望再次遍历,只能再使用另一个循环从头开始。而这里使用stream流就可以体现出他强大的功能和优雅了:
package com.wjh.util;
import java.util.ArrayList;
import java.util.List;
/**
* @author 26913
*/
public class TestMain {
public static void main(String[] args){
//创建一个List集合,存储姓名
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
//对list集合中的元素进行过滤,只要以张开头的元素,存储到一个新的集合中
//对listA集合进行过滤,只要姓名长度为3的人,存储到一个新集合中
//遍历listB集合
list.stream()
.filter(name -> name.startsWith("张"))
.filter(name -> name.length() == 3)
.forEach(name -> System.out.println(name));
}
}
运行结果:
https://wumangeng.github.io/2021/03/10/jdk8-xin-te-xing/#toc-heading-6
