欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java8新特性-Stream

程序员文章站 2022-06-15 17:23:59
...

—–通过学习尚硅谷视频所得—–

前言

咱们在sql中,可以对集合进行增删改插入和统计,但是在java程序中,对于一些集合, 都是通过循环的方式来处理里面的数据的.所以,对于大数量的集合,能不能充分利用多核的优势,并行去处理.
这里就来介绍一种这样的处理数据的风格—Stream
这种特性的引入,让我们更加便利一些函数式编程方法的使用.可以充分利用系统并行能力,不需要自己手工去做很多底层的工作.

定义

集合讲的是数据,流讲的是计算

Jenkins有这么一个概念pipeline. linux脚本命令中也会有一些接触.正常一个模块只专注于做一件事情,他们之间通过流水线方式连接起来.

从函数式编程的理论角度来说, stream 表示的是一个叫monad的结构. 具体monad 参考这篇博客:http://www.ruanyifeng.com/blog/2015/07/monad.html

使用

创建流

//1.可以通过Collection 系列集合提供的stream()方法或parallelStream() 顺序流或并行流
List<String> list=new ArrayList<>();
Stream<String> stream1=list.stream();

//2.通过Arrays 中的静态方法 stream()获取数组流
Employee[] emps=new Employee[10];
Stream<Employee> stream2=Arrays.stream(emps);

//3.通过stream类中的静态方法of(),通过显示值创建一个流,可以接受任意数量的参数
Stream<String> stream3=Stream.of("aa","bb","cc");

//4.函数创建流:创建无线流
Stream<Integer> stream4= Stream.iterate(0,(x) -> x+2);
stream4.limit(10).forEach(System.out::print);
//生成
Stream.generate(()-> Math.random())
      .limit(5)
      .forEach(System.out::println);

中间操作

惰性操作

流是一种惰性操作,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理

List<Employee> employees = Arrays.asList(
    new Employee("张三", 18, 9999.99),
    new Employee("李四", 58, 5555.55),
    new Employee("王五", 36, 3333.33),
    new Employee("田七", 12, 8888.88)
);

来个小例子: 取出员工年龄大于35岁的

Stream<Employee> stream = employees.stream()
                .filter((e) -> {
                    System.out.println("Stream API的中间操作");
                    return e.getAge() > 35;
                });

这里没有写终止操作,那么打印没有任何内容
java8新特性-Stream

如果现在加上了终止操作

Stream<Employee> stream = employees.stream()
                .filter((e) -> {
                    System.out.println("Stream API的中间操作");
                    return e.getAge() > 35;
                });
        //终止操作,即惰性求值
        stream.forEach(System.out::println);

我们来看效果:
java8新特性-Stream
而在终止操作时将中间操作一次性全部处理

stream执行顺序:
是按照流水线的方式执行的,不需要额外利用集合的数据结构来保存中间结果的.
举个例子:
java8新特性-Stream

筛选和切片

  • filter-接收Lambda,从流中排除某些元素
  • limit-截断流,使其元素不超过该给定数量
  • skip(n) -跳过元素,返回一个扔掉了前n个元素的流.若流中元素不足n个,则返回一个空流.与limit(n)互补
  • distinct-筛选,通过流生成元素的hashCode()和equals()去除重复元素

映射

  • map-接收Lambda,将元素转换成其他形式或提取信息.接收一个函数作为参数,该参数会被应用到每一个元素上,并将其映射成一个新的元素.
  • flatMap-接收一个函数作为参数,将流中的每一个值都换成另一个流.然后把所有流连接成一个流

排序

  • sorted()-自然排序(Comparable)
  • sorted(Comparator com)-定制排序(Comparator)

终止操作

在讲中间操作的时候,我们看上面的代码:filter运算仅仅过滤了stream里的元素,返回的依然是一个Stream类型.如果我们有一些类型转换的话,实际上也只是将一种类型参数的stream转换成另一种stream. 二终止操作, 它是将一个stream转换成了一个list或者toset设置void等等. 这些方法才称之为终止运算方法.

查找和匹配

  • allMatch–检查是否匹配所有元素
  • anyMatch–检查是否至少匹配一个元素
  • noneMatch–检查是否没有匹配所有元素
  • findFirst–返回第一个元素
  • findAny–返回当前流中的任意元素
  • count–返回流中元素的总个数
  • max–返回流中最大值
  • min–返回流中最小值
  • foreach–内部迭代

规约

  • reduce 可以将流中元素反复结合起来,得到一个值

收集

  • collect-将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法

并发parallelStream

引入的Fork/Join并行计算框架,能通过并行方式来拆分任务.不需要自己编写一行多线程的代码,就可以写出高性能的并发程序

总结

stream遵循的原则是: 告诉我做什么,别管我怎么做的.一个stream pipeline中,首先得有一个数据源,可能是数组或集合. 而在流操作过程中不会修改源中的数据.有多个中间操作,每个中间操作会将接受到的流转换成另一个流. 最后有一个终止操作,会生成一个最终结果.
不像传统数据结构, 事先分配内存空间, 啥时候用,啥时候再计算.默认是串行执行.也有简单支持并行计算的.