Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

06 | Stream如何提高遍历集合效率?

刘超 2019-06-01
你好,我是刘超。
上一讲中,我在讲 List 集合类,那我想你一定也知道集合的顶端接口 Collection。在 Java8 中,Collection 新增了两个流方法,分别是 Stream() 和 parallelStream()。
通过英文名不难猜测,这两个方法肯定和 Stream 有关,那进一步猜测,是不是和我们熟悉的 InputStream 和 OutputStream 也有关系呢?集合类中新增的两个 Stream 方法到底有什么作用?今天,我们就来深入了解下 Stream。

什么是 Stream?

现在很多大数据量系统中都存在分表分库的情况。
例如,电商系统中的订单表,常常使用用户 ID 的 Hash 值来实现分表分库,这样是为了减少单个表的数据量,优化用户查询订单的速度。
但在后台管理员审核订单时,他们需要将各个数据源的数据查询到应用层之后进行合并操作。
例如,当我们需要查询出过滤条件下的所有订单,并按照订单的某个条件进行排序,单个数据源查询出来的数据是可以按照某个条件进行排序的,但多个数据源查询出来已经排序好的数据,并不代表合并后是正确的排序,所以我们需要在应用层对合并数据集合重新进行排序。
在 Java8 之前,我们通常是通过 for 循环或者 Iterator 迭代来重新排序合并数据,又或者通过重新定义 Collections.sorts 的 Comparator 方法来实现,这两种方式对于大数据量系统来说,效率并不是很理想。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(47)

  • 奔跑的猪
    实践中大量采用stream大概有2年了吧,先是在Team内推广,后来在CodeReview中强制要求。
    个人以为,出发点并不是出于性能考虑,而是结合lambda,在编程思维上的转变,将大家对代码的关注点放在“行为传递”上面,而不是参数传递,阅读时也能省去模板语法产生的“噪音”。
    2019-07-26
    13
  • 小白猪
    思考题,由于流是并行处理,parallelList会存在并发问题,应该使用collect方法聚合
    2019-06-01
    11
  • 陆离
    思考题中这样的方式会造成null值和缺值
    因为arraylist不是线程安全的,例如线程一在size++后准备给index为size+1的位置赋值,这个时候第二个线程又给size++,这个线程一赋值的index就变成了size+2,在线程一赋值后,线程二又在size+2的位置赋值。
    这样的结果就是size+1的位置没有值null,size+2的位置为线程二赋的值,线程一赋的值被覆盖。
    正确的方式应该是使用collect()
    2019-06-01
    7
  • (´田ω田`)
    感觉这一节课已经值回了整个课程的票价,给老师点赞!

    思考题:Stream并行执行,无法确认每个元素的处理顺序,最后parallelList中的数字是无序的

    作者回复: 思考题中的问题是在并行操作arraylist时,需要考虑线程安全问题

    2019-06-01
    5
  • 一路看风景
    老师您好,在容器盛行的微服务环境下,以及大数据处理流行的潮流中,我觉得stream的应用空间多少有些尴尬呢,不知是不是我的理解有误。即:单核容器运行的环境下stream没了性能优势,大数据的处理又有大数据平台去完成使命,所以是不是意味着我们可以从stream得到的最大收益变成了流式编程和函数式编程带来的代码易读和易用性了呢?

    作者回复: 是的,但未必所有公司都有构建大数据的能力,而且一些公司有自己的中间件团队,例如文章开始说到的分表分库的查询操作,使用stream的并行操作就有优势了

    2019-06-01
    1
    4
  • Loubobooo
    parallelList集合里呈现的是无序的数字,是这样吗?

    作者回复: 对的,可能会出现少数字、无序以及异常情况

    2019-06-01
    4
  • 圣西罗
    老师,现在网上有些说法做测试用lambda比普通for循环速度慢五倍,因此有人拒绝用。实际情况是什么样呢?如果我自己想测,应该怎么尽可能排除外因干扰,测一下他们的实际效率对比?

    作者回复: 当应用程序以前没有使用lambda表达式时,会动态生成lambda目标对象,这是导致慢的实际原因。我们可以在运行加载后,也就是初次测试之后,紧接着后面加几个for循环,再测试几次,对比下性能。

    虽然单独使用lambda表达式在初次运行时要比传统方式慢很多,但结合stream的并行操作,在多核环境下还有有优势的。

    2019-06-01
    3
  • Andy
    感觉stream这种中间操作和终结操作 跟spark中转换操作和处理操作 思想很像,懒加载

    作者回复: 是的,好的实现思想会被应用到各个地方

    2019-10-21
    2
  • N
    老师有个问题请教一下,公司业务代码中有大量stream对集合遍历,过滤,聚合的用法,但都是串行的,因为大部分数据量不是很大,请问数据量多大的时候才有必要使用并行提高效率呢?

    作者回复: 上万数量级使用并行可以提高效率。

    2019-07-14
    2
  • 阿厚
    老师,请教2个问题:
    1.有什么分表分库中间件推荐么?
    2.分表分库以后,查询分页怎么办呢?

    作者回复: 之前用过sharing-jdbc以及mycat,一个明显的区别是sharing-jdbc是嵌入方式,而mycat是基于proxy,所以理论上来说 proxy方式会有性能损耗。现在我们在使用sharing-jdbc,这里不打广告,两个中间件都有自己的优势。

    分页查询是基于我这篇文章说的方式,将每个分表的数据结果集查询出来,通过归并排序计算出。
    具体的实现方式有区别,本次专栏的后面课程也会具体讲到。

    2019-06-06
    2
  • Darren
    最终的结果无序,且可能结果都是不正确的,因为ArrayList是线程不安全的
    2019-06-04
    2
  • QQ怪
    是不是该把思考题中的arraylist换成线程安全的copyOnwriteList就可以解决线程不安全问题?

    作者回复: 对的,但copyOnwriteList更适合某一时间段统一新增,且新增时避免大量操作容器发生。比较适合在深夜更新黑名单类似的业务。

    2019-06-03
    2
  • 小辉辉
    ArrayList是线程不安全的集合,而当前又用了并行流去处理,所以会出现有异常、少数据或者正常输出结果这三种情况。
    2019-06-02
    2
  • bro.
    老师,这么早更新,读完感觉跟rxjava设计思想很接近,不订阅前面过滤条件都不会真正的运行!
    2019-06-01
    2
  • 郑晨Cc
    课程好值啊 全是干货
    2019-06-03
    1
  • Liam
    parallel Stream 的并发机制是通过ForkJoinPool实现的,它的通用线程池是一个无界队列,想问下,数据量很大的时候,比如1w个元素,它分片的依据是什么,每个分片多大;子任务比较多的时候,会不会严重消耗内存以及频繁触发GC等
    2019-06-01
    1
  • Liam
    并发操作一个ArrayList,会有线程安全问题?

    作者回复: 对的

    2019-06-01
    1
  • 龙疯疯
    为什么聚合操作是线程安全的呢。
    2019-12-08
  • 丽儿
    有点类似于spark中rdd操作
    2019-12-05
  • 开心小毛
    使用stream是否有节省内存消耗的考虑,例如当需要遍历一个含上万条目的数据库查询结果。
    2019-11-19
收起评论
47
返回
顶部