Java8 Stream流遍历的方式

原文出处:https://blog.csdn.net/sarielangel/article/details/83899377
首先先说明,这篇文章的对比有失公允,stream()和parallelStream()差距还是挺大的,用parallelStream()这种开线程的玩意和单线程比较,有点不公平。

Stream流是一个集合元素的函数模型,它并不是集合,也不是数据结构,其本身并不存储任何元素(或其地址值),它只是在原数据集上定义了一组操作。

Stream流不保存数据,Stream操作是尽可能惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作。

Stream流也不会改变原有数据。

具体Stream流的知识请大家自行搜索,仅仅以循环效率来考虑,确实有点一叶障目。

以下内容大家看看就好:

————————————————————————————————————————————

java8新出的循环方式,在网上有大量的道友说用流的方式效率反而更低了。

大量的结论表明,这种方式只是语法糖(for-forEach-stream三种遍历方法执行效率比较与选用思考 - ZZY1078689276的专栏 - CSDN博客
https://blog.csdn.net/ZZY1078689276/article/details/79430772)这篇文章一样的内容看了不止一次,我都不知道谁先写的。。

不过,耳听为虚,眼见为实,上代码亲自试验:

public static void main(String[] args) {
    // 测试源
    List<String> sourceList = new ArrayList<>();
    for (int i = 0;i<10;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));
}

结果如下:

数据条数:10
普通for循环用时:0
增强for循环用时:0
forEach循环用时:43
forEach-Stream循环用时:6

好吧,数据少了点,不过结果也很明显了,使用forEach循环耗时最多,流启动也很耗时。

不过,让我们把循环次数提升至100W如何?

数据条数:1000000
普通for循环用时:3
增强for循环用时:10
forEach循环用时:46
forEach-Stream循环用时:33

forEach-Stream方式用时增加了,不过forEach用时并没有明显增加,再来一次:

数据条数:1000000
普通for循环用时:3
增强for循环用时:7
forEach循环用时:38
forEach-Stream循环用时:31

exm?forEach循环用时反而减少了是什么情况?不过今天我不研究原理,只看结论的话,for循环和增强for循环至少还是比新出的forEach-Stream要强很多的。

但这么一来,难道新功能真的只是语法糖么?

有人问我doSome()做了什么?实际上我什么都没做,但如果我真的做了什么呢?

比如等待一毫秒?

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

再来一次:

数据条数:10000
普通for循环用时:10025
增强for循环用时:10009
forEach循环用时:10067
forEach-Stream循环用时:1567

Duang!!!!!!!

forEach-Stream的效率获得了碾压式的胜利!有人说是因为jvm预热原因,但先且不论预热的是什么(通常是指启动时加载的东西),预热这种一次性的行为怎么可能取得这么大的提升?

于是,让我们打印一下doSome()的线程
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-4
ForkJoinPool.commonPool-worker-6
ForkJoinPool.commonPool-worker-2
main
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-6
main
ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-4
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-5
main

So,还用我解释什么么?

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

遍历Java集合可以使用Java 8引入的Stream方式Stream提供了一种对集合进行操作的高阶抽象。通过使用Stream,可以使用类似于SQL语句的方式对集合进行查询和操作。下面是一个使用Stream遍历集合的示例代码: ```java import java.util.ArrayList; import java.util.stream.Stream; public class StreamDemo { public static void main(String[] args) { ArrayList<String> webSites = new ArrayList<>(); webSites.add("baidu"); webSites.add("google"); webSites.add("weibo"); // 使用Stream遍历集合 webSites.stream().forEach(e -> { System.out.println(e); }); } } ``` 在这个示例中,我们创建了一个ArrayList集合`webSites`,并向其中添加了三个元素。然后,我们使用`stream()`方法将集合转换为,之后使用`forEach()`方法对中的每个元素进行遍历,并将元素打印出来。这样就可以使用Stream对集合进行遍历了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Stream遍历集合,对集合中数据进行过滤](https://blog.csdn.net/qq_40649503/article/details/108762599)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Java8 用Stream代替传统的集合遍历](https://blog.csdn.net/joshua317/article/details/128244212)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值