当前位置: 首页 > news >正文

流式编程 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对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道

Integer transactionsIds = 
 		roomList.stream()  //将List转换为stream对象
 		.filter(b -> b.getLength() == 10) //针对stream种的数据元素进行过滤,只使用为true
 		.sorted((x,y) -> x.getHigh() - y.getHigh()) //针对stream种的数据进行自定义规则的排序
		.mapToInt(Room::getWidth)//从集合元素通过调用当前对象getWidth方法获取对应的int类型数据
		.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<Integer> list = ...;

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

创建方法2:

Stream<Integer> stream = list.parallelStream();
Stream<Integer> stream = list.stream();

创建方法3:

Collection.stream()用Java集合都创建一个Stream
特殊类型的Stream实现
IntStream、LongStream和DoubleStream
官方建议使用对应类型的Stream?
当然也可以用`Stream<Integer>`、`Stream<Long>`和`Stream<Double>`,但是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<String> stream = br.lines();


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

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

iterate()方法接受一个参数函数用来创建无限Stream
Stream<BigInteger> 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); });

相关文章:

  • FPGA刷题——数据位宽转换(整数倍非整数倍)
  • 自动控制原理7.2---信号的采样与保持
  • 深挖全媒体多模态数据价值,蜜度亮相2022世界人工智能大会
  • Qt开发及建立工程
  • 四十四、模板层
  • Django-ORM 单表查询
  • 基础数据结构详解
  • 淘宝天猫店铺商品API,店铺商品分类接口代码对接教程
  • 神器 SpringDoc 横空出世!最适合 SpringBoot 的API文档工具来了
  • 剑指offer68-77二分查找、排序
  • vue filters过滤器分别在template和script中使用
  • ssm毕设项目基于Java的城市公交查询系统ac5p2(java+VUE+Mybatis+Maven+Mysql+sprnig)
  • unity sdk -AppLovin MAX 广告聚合平台接入+Firebase统计
  • C#手动填充DataSet
  • coreutils5.0 uname命令和源码分析
  • Apache Zeppelin在Apache Trafodion上的可视化
  • gulp 教程
  • HTTP那些事
  • java正则表式的使用
  • mysql innodb 索引使用指南
  • python docx文档转html页面
  • Python爬虫--- 1.3 BS4库的解析器
  • React组件设计模式(一)
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • SQLServer插入数据
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • 测试开发系类之接口自动化测试
  • 大快搜索数据爬虫技术实例安装教学篇
  • 构建二叉树进行数值数组的去重及优化
  • 构造函数(constructor)与原型链(prototype)关系
  • 基于axios的vue插件,让http请求更简单
  • 开发基于以太坊智能合约的DApp
  • 如何使用 JavaScript 解析 URL
  • 新书推荐|Windows黑客编程技术详解
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 阿里云ACE认证学习知识点梳理
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #HarmonyOS:基础语法
  • #Z2294. 打印树的直径
  • #宝哥教你#查看jquery绑定的事件函数
  • $.ajax,axios,fetch三种ajax请求的区别
  • (C语言)球球大作战
  • (Forward) Music Player: From UI Proposal to Code
  • (Python第六天)文件处理
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (力扣)循环队列的实现与详解(C语言)
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (七)c52学习之旅-中断
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转) ns2/nam与nam实现相关的文件