Stream总结

目录流是什么生成流使用方法map/flatMapfilterforEachpeek聚合操作reduce收集结果collect将结果收集到map中分组和分片join和统计功能并发流及其效率并发的演变生成并发流并发性能测试collect()保证有序性并发流的实现方法parallelStream的实现:ForkJoinPoo...
摘要由CSDN通过智能技术生成

目录

流是什么

生成流

使用方法

map/flatMap

filter

forEach

peek

聚合操作reduce

收集结果collect

将结果收集到map中

分组和分片

join和统计功能

并发流及其效率

并发的演变

生成并发流

并发性能测试

collect()保证有序性

并发流的实现方法

parallelStream的实现:ForkJoinPool

什么时候用并发流?

 

流是什么

Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。

上面是官方的解释,我认为流是一种处理数据的思路,或者说是一种更好的方法,以前我们总是把数据一个一个遍历元素并对其执行某些操作, 使用流就是我先定义要进行什么操作,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

那不是还要进行遍历吗?没有节省开支啊. 

首先我们节省了代码量,使用了更优雅的代码; 其次对于空间复杂度,如果入参是流的形式,就可以大大的节省内存占用,意思就是我们之前的数据是全部放入内存中再进行处理,非常巨大的集合类会占用大量的内存,而现在可以来一个数据就用我定义好的处理方式处理一个,因为Stream的元素是在访问的时候才被计算出来(延迟计算),而不用占用大量的内存.而且对于时间复杂度,Stream 依赖于 Java7 中引入的 Fork/Join 框架可以实现并行, 来拆分任务和加速处理过程。

  1. 对于大量数据可以不存入内存, 流式的处理
  2. 更简洁的代码
  3. 可以很方便的并行处理

总结一下,对集合进行代码简洁,清晰但不一定易读(可读性其实不高,而且不方便debug,不抛出checked异常),不一定高效(效率其实有时不如for循环) 的转换、过滤、聚合等操作,“高级版”的迭代器,而和迭代器又不同的是,Stream可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出(但并发功能慎用,对于IO密集型操作,都使用默认的线程池会导致其他任务被阻塞)

stream的意义是更优雅(简洁)的实现一些数据操作(主要是迭代),但效率不一定比传统写法高.因为其简洁性,不应该在其中写入太多代码.

生成流

当我们使用一个流的时候,通常包括三个基本步骤:

获取一个数据源(source)→ 数据转换→执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道.

流的操作类型分为两种:

  • Intermediate(中间操作):一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。
  • Terminal(终端操作):一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。

流是一个懒加载的模式 未结束流前不会进行操作,只要结束流以后才会操作返回结果.

                                                                                            Stream操作分类

中间操作(Intermediate operations)

无状态(Stateless)

map() mapToInt() mapToLong() mapToDouble()

flatMap() flatMapToInt() flatMapToLong() flatMapToDouble()

filter()

peek()

unordered()

有状态(Stateful)

distinct() sorted() limit() skip()

终端操作(Terminal operations)

非短路操作

forEach() forEachOrdered() toArray() reduce() collect() max() min() count()

短路操作(short-circuiting)

anyMatch() allMatch() noneMatch() findFirst() findAny()

1. 直接对collection.stream()

List<String> list = Arrays.asList("1","2","3","4");
Stream<String> stream1 = list.stream();

2.对于数组

String[] s = new String[]{"1","2","3","4"};
Stream<String> stream2 = Arrays.stream(s);

3.直接构建一个流

Stream<String> stream3 = Stream.of("1","2","3","4")
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值