文章目录

  • Stream介绍(摘抄)
  • 流的创建
  • 流的转换
  • 中间操作
  • 常用
  • 匹配
  • 查找元素
  • 计数和极值
  • 终止操作
  • Collectors 具体方法
  • 注意事项


Stream介绍(摘抄)

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。JDK8新特性。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选,排序,聚合等。

Stream有以下特性及优点:

  • 无存储。Stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
  • 为函数式编程而生。对Stream的任何修改都不会修改背后的数据源,比如对Stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新Stream。
  • 惰式执行。Stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
  • 可消费性。Stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

流的创建

  • 集合 Collection.stream()
  • 静态方法 Stream.of
  • 数组 Arrays.stream
// 流的创建
        // 1.集合
        List<String> list = Arrays.asList("a", "b", "c");
        Stream<String> listStream = list.stream();
        Stream<String> listParallelStream = list.parallelStream();

        // 2.数组
        Integer[] numberArray = {1,2,3,4};
        Stream<Integer> arrayStream1 = Arrays.stream(numberArray);
        Stream<Integer> arrayStream2 = Stream.of(numberArray);
        Stream<Integer> arrayParallelStream = Stream.of(numberArray).parallel();

        // 3.多个元素
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);

        // 4.单一元素
        Student student = new Student(1, "gxzhang", BigDecimal.ZERO);
        Stream<Student> studentStream = Stream.of(student);

stream为串行流,parallelStream并行流可利用机器多核并发,效率更高,默认并发数为机器cpu核数。

流的转换

// 流的转换
// 普通流转并行流
Stream<String> parallel = listStream.parallel();
// Stream<Integer> -> IntStream
IntStream intStream2 = integerStream.mapToInt(value -> value.intValue());
// IntStream -> Stream<Integer>
Stream<Integer> integerStream3 = intstream.boxed();

中间操作

常用

  • filter(Predicate) 筛选流中某些元素
  • map(Function f) 接收流中元素,并且将其映射成为新元素,例如从student对象中取name属性
  • flatMap(Function f) 将所有流中的元素并到一起连接成一个流
  • peek(Consumer c) 获取流中元素,操作流中元素,与foreach不同的是不会截断流,可继续操作流
  • distinct() 通过流所生成元素的equals和hashCode去重
  • limit(long val) 截断流,取流中前val个元素
  • sorted(Comparator) 产生一个新流,按照比较器规则排序
  • sorted() 产生一个新流,按照自然顺序排序

匹配

  • booelan allMatch(Predicate) 都符合
  • boolean anyMatch(Predicate) 任一元素符合
  • boolean noneMatch(Predicate) 都不符合

查找元素

  • findFirst——返回第一个元素
  • findAny——返回当前流中的任意元素

计数和极值

  • count——返回流中元素的总个数
  • max——返回流中最大值
  • min——返回流中最小值
// 中间操作
        // filter:过滤值为为 "a" 的元素 filter的值为false时会被过滤
        list = listStream.filter(value -> "a".equals(value)).collect(Collectors.toList());
        // map 将值依次进行映射处理;将数据每个字符串后加‘-’符号
        list = listStream.map(value->value+"-").collect(Collectors.toList());
        // anyMatch 任意符合 返回布尔类型; 判断元素是否存在”a“
        boolean b = listStream.anyMatch(value -> "a".equals(value));

        // 流的扁平化
        // 将 数组["hello", "world"] 转变成 ["h","e","l","o","w","r","d"] 并将元素去重
        String[] strings = {"hello", "world"};
        // 这样返回的结果为 String[]数组类型的集合,而我们需要将List<String>类型的
        // 原因是因为map中将一个元素生成了多个元素返回了一个String[]数组类型
        List<String[]> collect = Stream.of(strings)
                .map(word -> word.split(""))
                .distinct()
                .collect(Collectors.toList());
        // 采用flatmap进行流扁平化
        List<String> collect1 = Stream.of(strings).
                flatMap(word -> Arrays.stream(word.split("")))
                .distinct()
                .collect(Collectors.toList());

终止操作

  • foreach(Consumer c) 遍历操作
  • collect(Collector) 将流转化为其他形式
  • max(Comparator) 返回流中最大值
  • min(Comparator) 返回流中最小值
  • count 返回流中元素综述

Collectors 具体方法

  • toList List<T> 把流中元素收集到List
  • toSet Set<T> 把流中元素收集到Set
  • toCollection Coolection<T> 把流中元素收集到Collection中
  • groupingBy Map<K,List<T>> 根据K属性对流进行分组
  • partitioningBy Map<boolean, List<T>> 根据boolean值进行分组
// 终止操作
        // 流的遍历
        listStream.forEach(value-> System.out.println(value));
        listStream.forEach(value-> System.out.println(value));
        listStream.forEach(System.out::println);
        listStream.forEach(value -> {
            // 多条语句用花括号
            System.out.println("二哈");
            System.out.println(value);
        });
        // 归约,计算数和;0 为identity初始值,a将被赋值为上次计算结果(初始为identity值),b流中元素
        int sum = intstream.reduce(0, (a, b) -> a + b);
        // 收集 将处理后的结果返回对应的类型数据
        List<Integer> list1 = integerStream.collect(Collectors.toList());
        // 其他
        // 最大值
        int max = intstream.max().getAsInt();
        // 最小值
        int min = intstream.min().getAsInt();
        // 和
        intstream.sum();

注意事项

流一旦执行了终止操作就不再可用,必须需要重新获取流。

流式编程为语法糖,最终编译后执行效果和不加糖是一致的,只是语法糖帮我们提升了编程效率和常用操作的最优实现。

以上案例仅为方便说明用法,不可直接执行。

流的常用api以上已说明,案例只简单列举了常用的api用法,可根据简单介绍很容易上手。

欲练此功,必先多敲✊