# 第一章 简单体验一下 Stream 流

  • 我们使用 Stream 流的方式,可以用来遍历集合,对集合中的数据进行过滤等,Stream 流是在 jdk1.8 之后出现
  • 代码示例
public class DemoTextStream{
    public static void main(String[] args){
        // 创建一个 list 集合,用来存储姓名
        List<String> list = new ArrayList<>();
        list.add("李冰冰");
        list.add("彭于晏");
        list.add("李易峰");
        list.add("李沁");
        list.add("王思聪");
        // 对 List 集合的元素进行过滤,只要以张开头的元素,存储到一个新的集合中
        // 对 listA 集合进行过滤,只要姓名长度为三的人
        // 遍历集合
        list.Stream()
                .filter(name->name.startsWith("李"))
                .filter(name->name.length()==3)
                .foreach(name->System.out.println(name));
    }
}

# 流式思想的概述

对于流式思想,可以把它想象成工厂的 “流水线”。通过一系列的加工、过滤得到最后的产品


# 何为 Stream

  • Stream 流实际上是一个来自数据源的元素队列
  • Java 中的 Stream 并不会存储元素,而是按需计算
  • Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

# 第二章 获取 Stream 流的方式

  • java.util.stream.Stream<T> 是 java 中新加入的最常用的流接口

  • 获取流的两种方式
    • 所有的 collection 集合都可以通过 stream 默认方法获取流
    • Stream 接口的静态方法 of 可以获取数组对应的流 static<T> Stream<T> of(T...values) 参数是一个可变参数,可以通过这个方法传递一个数组
      • 代码演示:
      public class DemoMethodAcq{
          public static void main(String[] args){
              // 把集合转换为 Stream 流
              List<String> list = new Arraylist<String>();
              Stream<String> str = list.stream();
              Set<String> set = new HashSet<>();
              Stream<String> stream2 = set.stream();
              Map<String,String> map = new HashMap<>();
              // 获取键,存储到一个 Set 集合中
              Set<String> keyset =map.keyset();
              Stream<String> Stream3 = keyset.stream();
              // 获取值,存储到一个 Collection 集合中
              Collection<String> values = map.values();
              Stream<String> stream4 = values.stream();
              
              // 获取键值对
              Set<Map.Entry<String,String>> entries = map.entries();
              Stream<Map.Entry<String,String>> stream5 = entries.stream();
              // 把数组转换为 Stream 流
              Stream<Integer> stream6 = Stream.of(1,2,3,4,5);
              // 可变参数可以传递数组
              Integer[] arr = {1,2,3,4,5};
              Stream<Integer> stream7 = Stream.of(arr);
              String[] arr2 ={"a","bb","ccc"};
              Stream<String> stream8 = Stream.of(arr2);
          }
      }

# 第三章 Stream 流的常用方法

流模型的操作被分为两种方法:
     1. 延迟方法:   返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用(除了延时方法其他均为终结方法)
     2. 终结方法:   返回值类型不在是 Stream 接口自身类型的方法,因此不在支持类似 StringBuilder 那样的链式调用(终结方法包括 countforEach 方法)

# 1、forEach 方法(逐一处理)

  • 首先,此方法非 for 循环的 for-each 循环方法
  • 其标准格式为:
    void forEach(Consumer<? suoer T> action);

  • forEach 方法是通过接收一个 Consumer 接口函数,会使每一个流元素交给该函数处理
  • 可以简记为:
    • forEach 是用来遍历流数据的
    • 它是一个终结方法,遍历之后就不能继续调用 Stream 流中的其他方法
  • 代码演示:
    public class Demo_forEach{
        public static void main(String[] args){
            // 获取一个 Stream 流
            Stream<String> stream = Stream.of("张三""李四""w王五""赵六");
            // 使用 Stream 流中的方法 forEach 对 Stream 流中的数据进行遍历
            stream.forEach((String name)-> {
                System.out.println(name);
            });
            /* 简写可以这样:
             stream.forEach (name-> 
                System.out.println (name)
            );
            */
        }
    }

# 2、filter 方法(过滤)

  • 使用 filter 方法可以将一个流转换成另一个字节流
    Stream<T> filter(Predicate<? super T> predicate);
    • 此接口接收一个 Predicate 函数式接口参数作为筛选条件,即:
      boolean test(T t);
      • 该方法是 Predicate 接口中的一个抽象方法
    public class Demo_filter{
        public static void main(String[] args){
            // 创建一个 Stream 流
            Stream<String> stream = Stream.of("李冰冰","李易峰","彭于晏","李沁","王思聪");
            // 对 Stream 流中的元素进行过滤,筛选出姓 “李” 的人
            Stream<String> stream2 = stream.filter((String name)->{
                return name.startWith("李");
            });
            // 遍历 stream2
            stream.forEach(name-> System.out.println(name));
        }
    }
    • Stream 流属于管道流,只能被消费一次
    • 第一次 Stream 流调用完毕后,数据会流到下一个 Stream 上
    • 此时第一个 Stream 流消费完毕,就会关闭

# 3、map 方法(映射)

  • map 方法是将流中的元素映射到另一个流中,可以使用 map 方法
    <R> Stream<R> map{Function<? super T,? extends R> mapper};
    • 该接口需要一个 Function 的函数式接口参数
    • 使用的是 Function 接口的抽象方法:
      R apply(T t);

  • 代码演示:
    public class Demo_map{
        public static void main(String[] args){
            // 获取一个 String 类型的 Stream 流
            Stream<String> stream = Stream.of("1","2","3","4","5");
            // 使用 map 方法,把字符串类型的整数,转换(映射)到 Integer 类型的整数
            Stream<Integer> stream2 = stream.map((String s)->{
                return Integer.parseInt(s);
            });
            // 遍历 stream2
            stream2.forEach(i-> System.out.println(i));
        }
    }

# 4、count 方法(统计个数)

  • Stream 流通过 count 方法来对流中的元素进行统计,即:
    long count();
  • count 方法是一个终结方法,返回值是一个 Long 类型的整数,不能再继续调用 Stream 流中的其他方法
  • 代码示例:
    import java.util.stream.Stream;
    public class Demo_count{
        public static void main(String[] args){
            Stream<String> stream = Stream.of("李冰冰","李易峰","王思聪");
            Stream<String> result = stream.filter(s-> s.startWith("李"));
            System.out.println(result.count());// 输出为 2
        }
    }

# 5、limit 方法(截取使用前几个)

  • limit 方法可以对流进行截取,只取用前 n 个,即:
    Stream<T> limit(long maxSize);
    • 参数是一个 Long 类型,如果集合当前长度大于参数则进行截取,否则不操作
    • limit 方法是一个延迟方法,返回的是一个新的流,可以调用 Stream 流的其他方法
    • 代码展示:
    public class Demo_limit{
        public static void main(String[] args){
            // 获取一个 Stream 流
            String[] arr = {"李冰冰","李易峰","王思聪"};
            Stream<String> stream = Stream.of(arr);
            // 使用 Limit 对 Stream 流中的元素进行截取,只要前 2 个元素
            Stream<String> stream2 =stream.limit(2);
            // 遍历 stream2
            stream2.forEach(name-> System.out.println(name));
        }
    }

# 6、skip 方法(跳过前几个)

  • 如果需要跳过前几个元素,可以使用 skip 方法进行截取流,即:
    Stream<T> skip(long n);
    • 若要跳过的元素个数 n 大于流中元素的个数,则会截取流,得到一个长度为 0 的空流(新流)
    • 代码展示:
      public class Demo_limit{
              public static void main(String[] args){
              // 获取一个 Stream 流
              String[] arr = {"李冰冰","李易峰","王思聪"};
              Stream<String> stream = Stream.of(arr);
              // 使用 skip 跳过前 2 个元素
              Stream<String> stream2 =stream.skip(2);
              // 遍历 stream2
              stream2.forEach(name-> System.out.println(name));
          }
      }

# 7、concat 方法(组合)

  • 如果有两个流,需要合并为一个流,则需要使用 concat 静态方法,即:
    static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b);

    备注:这是一个静态方法,与 java.lang.String 当中的 concat 方法不同

    • 代码展示:
    import java.util.stream.Stream;
    public class Demo_concat{
        public static void main(String[] args){
            Stream<String> streamA = Stream.of("李冰冰");
            Stream<String> streamB = Stream.of("李易峰");
            Stream<String> result = Stream.concat(streamA,streamB);
        }
    }

请我喝[茶]~( ̄▽ ̄)~*

Peter Pan 微信支付

微信支付

Peter Pan 支付宝

支付宝