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

    Stream流(todo) - 图1
    这张图中展示了过滤、映射、跳过、计数等多步操作,这是一种集合元素的处理方案,而方案就是一种“函数模型”。图中的每一个方框都是一个“流”,调用指定的方法,可以从一个流模型转换为另一个流模型。而最右侧的数字3是最终结果。这里的 filter 、 map 、 skip 都是在对函数模型进行操作,集合元素并没有真正被处理。只有当终结方法 count执行的时候,整个模型才会按照指定策略执行操作。而这得益于Lambda的延迟执行特性。
    在使用for循环遍历一个集合或者数组的时候,for循环的语法是“怎么做”,其方法体才是“怎么做”。遍历是指每一个元素逐一进行处理,而并不是从第一个到最后一个顺次处理的循环,前者是目的,后者是方式。
    下面通过一个例子来对比以下传统的for循环遍历集合和使用stream流来遍历集合:

    1. package com.wjh.util;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. /**
    5. * @author 26913
    6. */
    7. public class TestMain {
    8. public static void main(String[] args){
    9. List<String> list = new ArrayList<>();
    10. list.add("张无忌");
    11. list.add("周芷若");
    12. list.add("赵敏");
    13. list.add("张强");
    14. list.add("张三丰");
    15. //对list集合中的元素进行过滤,只要以张开头的元素,存储到一个新的集合中
    16. List<String> listA = new ArrayList<>();
    17. for (String s : list) {
    18. if (s.startsWith("张")) {
    19. listA.add(s);
    20. }
    21. }
    22. //对listA集合进行过滤,只要姓名长度为3的人,存储到一个新集合中
    23. List<String> listB = new ArrayList<>();
    24. for (String s : listA) {
    25. if (s.length() == 3) {
    26. listB.add(s);
    27. }
    28. }
    29. //遍历listB集合
    30. for (String s : listB) {
    31. System.out.println(s);
    32. }
    33. }
    34. }

    运行结果:
    image.png
    每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。循环是做事情的方式,而不是目的。另一方面,使用线性循环就意味着只能遍历一次,如果希望再次遍历,只能再使用另一个循环从头开始。而这里使用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));
        }
    }
    

    运行结果:
    image.png
    https://wumangeng.github.io/2021/03/10/jdk8-xin-te-xing/#toc-heading-6