• 流式编程 stream


    流式编程 stream

    Stream中文称为流,通过将集合转换为这么一种叫做流的元素序列,通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作

    Java 8中的Stream是对集合Collection对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作或者大批量数据操作。

    Stream API借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用Stream API无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物
    Stream不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的Iterator。原始版本的Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如过滤掉长度大于10的字符串、获取每个字符串的首字母等,Stream会隐式地在内部进行遍历,做出相应的数据转换。Stream就如同一个迭代器Iterator,单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。
    而和迭代器又不同的是,Stream可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个item读完后再读下一个item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream的并行操作依赖于Java7中引入的Fork/Join框架(JSR166y)来拆分任务和加速处理过程。
    Stream 的另外一大特点是,数据源本身可以是无限的。
    当使用一个流的时候,通常包括三个基本步骤:获取一个数据源source → 数据转换 → 执行操作获取想要的结果。每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道

    1. Integer transactionsIds =
    2. roomList.stream() //将List转换为stream对象
    3. .filter(b -> b.getLength() == 10) //针对stream种的数据元素进行过滤,只使用为true
    4. .sorted((x,y) -> x.getHigh() - y.getHigh()) //针对stream种的数据进行自定义规则的排序
    5. .mapToInt(Room::getWidth)//从集合元素通过调用当前对象getWidth方法获取对应的int类型数据
    6. .sum(); // 针对整数值进行求和处理

    使用Stream步骤

    1. 创建Stream;
    2. 转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换)
    3. 对Stream进行聚合(Reduce)操作,获取想要的结果;

    创建stream

    流可以是顺序的也可以是并行的。顺序流的操作是在单线程上执行的,而并行流的操作是在多线程上并发执行的 

    创建方法1

    可以使用Arrays.stream()方法来使用Stream
    Integer[] array = new Integer[]{3,4,8,16,19,27,23,99,76,232,33,96};
    long count = Arrays.stream(array).filter(i->i>20).count();
    Collection.parallelStream使用并行流提高性能,处理任务时并行处理,前提是硬件支持,如果单核CPU,只会存在并发处理而不会并行
    - ParallelStream在使用上与Stream无区别,本质返回的都是一个流,只不过底层处理时根据条件判断是并行或者是串行
    - 并行流并不会按照原本的顺序轨迹执行,而是随机执行,当然对于forEach输出也可以做到顺序串行,
    List list = ...;

    使用List创建一个并行流对象Stream

    创建方法2:

    Stream stream = list.parallelStream();
    Stream stream = list.stream();

    创建方法3:

    Collection.stream()用Java集合都创建一个Stream
    特殊类型的Stream实现
    IntStream、LongStream和DoubleStream
    官方建议使用对应类型的Stream?
    当然也可以用`Stream`、`Stream`和`Stream`,但是boxing/unboxing
    会很耗时,所以特别为这三种基本数值型提供了对应的Stream
     IntStream.of(new int[]{1,2,3}).forEach(System.out::println);
    IntStream.range(1,10).forEach(System.out::println);
    IntStream.rangeClosed(1,3).forEach(System.out::println)
    针对BufferedReader可以生成stream实现一行一行数据的读取
    BufferedReader br = new BufferedReader(new FileReader("d:/aaa.txt"));
    Stream stream = br.lines();


    Stream接口创建无限Stream的静态方法

    generate()方法接受一个参数函数用来创建无限Stream的静态方法Stream stream = Stream.generate(() -> "test").limit(10);
    String[] strArr = stream.toArray(String[]::new);
    System.out.println(Arrays.toString(strArr));

    iterate()方法接受一个参数函数用来创建无限Stream
    Stream bigIntStream = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.TEN)).limit(10);
    BigInteger[] bigIntArr = bigIntStream.toArray(BigInteger[]::new);
     System.out.println(Arrays.toString(bigIntArr));

    遍历操作

    Stream提供了方法forEach来迭代流中的每个数据

    Random random = new Random();
    random.ints().limit(10).forEach(System.out::println);

    forEach方法接收一个Lambda表达式,然后在Stream的每一个元素上执行该表达式。不能修改自己包含的本地变量值,
    也不能用break/return之类的关键字提前结束循环
      
    numbers.stream().forEach(number->{ System.out.println(number); });

  • 相关阅读:
    怎么把网页上的接口信息导入postman
    centOS7安装rabbitMQ
    Dubbo高手之路4,Dubbo服务提供者详解
    idea中maven依赖爆红的排查步骤
    基于Intel Lake-UP3平台为半导体与集成电路测试设备提供优异计算性能
    Swift基础
    win 中删除 “/xx..“ 之类的文件夹
    毕业设计-基于机器视觉的手写字识别系统
    在Windos 10专业版搭建Fyne(Go 跨平台GUI)开发环境
    A40i使用笔记:时区设置
  • 原文地址:https://blog.csdn.net/weixin_50518344/article/details/126670572