流 这个概念很抽象,记得在初学java的时候就问过老师,然而并吗,没有给我一个很好的解释,依然抽象
最近看到一个比较好理解的说法:
流就像一个管道,读取数据、处理数据、输出数据
再精确一点:
流就像一个管道,读取一部分数据、处理一部分数据,最后输出数据
所以流跟for循环是有质的区别:
流:

  1. 流不是读取整个需要处理的源,而是基于迭代器,每读取解析完一行数据,就发送到Stream流里,下游,map也好,flatMap也好forEach也好等等,都是每当上游发送一个数据,就处理一个数据,因为是流式的,看起来就跟遍历一样

  2. 流实际上并不存储元素。元素是按需计算的。可以将流视为延迟构造的Collection,可以在需要它们时计算其值。

  3. 流是消耗品。在流的生存期内,流的元素仅被访问一次。如果要重新访问流中的同一元素,则需要根据源重新生成新的流。
    for循环:
    for循环是有限的,它会将整个遍历对象读取到内存中,再进行遍历

那么Stream为什么能实现集合遍历呢?
跟上边说的文件遍历性质是一样的,就是直接借助集合的迭代器,把集合的数据一个个发送到流里,然后下游处理,形成了看是遍历的操作,Stream处理要完成消息的传递,里面还要有其他很多辅助东西的处理,比如上游消息已经全发完了得通知到下游吧。
从而就遍历上来说,Stream的性能是不可能比循环更快的

话不要说得太死

在大数据量的处理上,stream流的效率往往会比for循环要高一些
这是因为stream流在处理大数据的时候使用了并行流:parallelStream

Stream并行处理的过程会分而治之,也就是将一个大任务切分成多个小任务,这表示每个任务都是一个操作。

同时需要注意使用并行流时的线程安全问题:
加锁、使用线程安全的集合或者调用Stream的 toArray() / collect() 操作就是满足线程安全的了。

总结:
数据量少的情况,for循环效率一般要高于stream流
数据量大的情况,stream流的效率一般要高于for循环