Java Stream流封装速度竟然如此给力!

举报
辰兮 发表于 2022/03/23 00:17:39 2022/03/23
【摘要】 【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,博客昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后...

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,博客昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿你们奔赴在各自的热爱中…


一、Stream序言

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。
在这里插入图片描述

简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。


二、Stream测试

项目案例:第一次接触Java-Stream流,记得当时要查询帖子列表,本身查询就是三个表的连表查询外,还要封装点赞,是否点赞,等等一系列属性,用传统的for循环封装速度太慢了,会带给用户不好体验,于是一个大佬帮我优化了一下代码用stream流帮我封装等一系列属性时间也节省了三分之二的时间

爱了爱了,来找找网上案例一起尝试学习一下

在这里插入图片描述

整理了一下常见的for循环foreach等等和stream流的比较

public class Test {
    public static void main(String[] args) {
        // 测试源
        List<String> sourceList = new ArrayList<>();
        for (int i = 0;i<10000;i++) {
            sourceList.add("第" + i + "条数据");
        }
        System.out.println("数据条数:" + sourceList.size());
        long a1=System.currentTimeMillis();
        for (int i = 0;i < sourceList.size();i++) {
            doSome();
        }
        long a2=System.currentTimeMillis();
        System.out.println("普通for循环用时:" + (a2-a1));


        long b1=System.currentTimeMillis();
        for (String t:sourceList) {
            doSome();
        }
        long b2=System.currentTimeMillis();
        System.out.println("增强for循环用时:" + (b2-b1));

        long c1=System.currentTimeMillis();
        sourceList.forEach((t)-> doSome());
        long c2=System.currentTimeMillis();
        System.out.println("forEach循环用时:" + (c2-c1));

        long d1=System.currentTimeMillis();
        sourceList.parallelStream().forEach((t)-> doSome());
        long d2=System.currentTimeMillis();
        System.out.println("forEach-Stream循环用时:" + (d2-d1));



    }
    private static void doSome() {
        try {
            Thread.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

当我们数据是一万条的时候可以发现forEach-Stream流明显的速度优势

数据条数:10000
普通for循环用时:19804
增强for循环用时:19645
forEach循环用时:19707
forEach-Stream循环用时:3702


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

数据量比较小的时候好像看不到明显的优势

数据条数:10
普通for循环用时:21
增强for循环用时:20
forEach循环用时:62
forEach-Stream循环用时:27

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

三、Stream小结

JDK1.8的stream流操作和for循环操作到底谁的性能高?

如果在循环体中有复杂的业务、调用远程接口或数据库就用stream,因为stream是多线程方式并行执行,但是其调用线程池必然会消耗性能,所以简单的操作固然还是for循环效率高。具体的应用我们更加具体的业务场景来。

stream().forEach用的多线程方式,其调用线程池的时候必然会耗费更多的时间。但如果你在循环内要处理的事情很多,或者要循环调用远程接口/数据库的时候,无疑极大的提升了效率

在编写代码的过程中,我们究竟采用哪种遍历方式比较好?!

这个得有一个选择标准,如果单纯的以运行效率为主,那还是采用传统的for循环,若要简化代码量,那就选用stream。


使用 Stream 的建议

  • 1、简单的迭代逻辑,可以直接使用 iterator,对于有多步处理的迭代逻辑,可以使用 stream,损失一点几乎没有的效率,换来代码的高可读性是值得的;

  • 2、单核 cpu 环境,不推荐使用 parallel stream,在多核 cpu 且有大数据量的条件下,推荐使用 paralle stream;

  • 3、stream 中含有装箱类型,在进行中间操作之前,最好转成对应的数值流,减少由于频繁的拆箱、装箱造成的性能损失;


Stream小结

我们可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“封装某些属性”、“过滤长度小于3的字符串”、“获取每个字符串的首字母”等,具体的操作还是要进一步学习Stream流的相关用法,值得学习实践。


The best investment is to invest in yourself.

在这里插入图片描述

2020.11.24 晚22:48 愿你们奔赴在自己的热爱里!

文章来源: blessing.blog.csdn.net,作者:辰兮要努力,版权归原作者所有,如需转载,请联系作者。

原文链接:blessing.blog.csdn.net/article/details/110099425

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。