Java8的流式编程-“花哨的iterator”

Java不知不觉已经出到了14了,如果再对Java8的“新”特性敬而远之就有点说不过去了,就像是在微信横行的年代仍然使用短信一样,所以最近赶紧用起了流式编程,感觉就两个字“真香”。

流式编程的核心就是操作流,这个流可以自己生成:

Stream.builder()

但是更多的是从集合中去生成

new ArrayList<Activity>.stream()

既然已经拿到了流 那就要对流进行操作了 对流的操作就有很多了 map(),distinct(),sorted(),foreach(),collect()…..其中很多操作都是可以顾名思义的 但是还有一些是不能的 比如reduce()或者上面的map(),这里就不说这些函数具体的功能再拾人牙慧了,其他人已经说的很详尽了,大家可以搜搜看,总之就是通过对流的操作,从而操作集合。

流式编程的操作从执行的顺序上分为两种,中间操作( filter ,limit,sort,map,distinct。。。)和最终操作(reduce foreach collect close allmatch anymatch。。。)从属于中间操作的那些操作,不是顺序执行的,而是等到最终操作要执行的时候,在最终操作执行前进行执行,这也是我的一个朋友的断点打在中间操作的函数上不起作用的原因。

怎么判断一个操作是中间操作还是最终操作呢?其实很简单,看返回值就可以了 ,凡是返回Stream的 基本都是中间操作,既然如此,那么中间操作就可以连起来形成了pipeline,而且中间操作上面也提到了 都是lazy的加载形式,这种方式更加有利于像延迟加载,短路,循环合并等操作。

而最终操作基本是将经过中间操作处理过后的Stream进行处理,或是聚合成list 或是返回Integer 也可能是void这种,而且最终操作之所以是最终,就是因为他操作之后调用了Runnble 进行关流,流中所有数据都会被销毁

说到这里为止,其实流的操作都可以被Iterator所代替 ,但是如果真的是这样那么流也就没有什么存在必要了,在我看来,流相对于迭代器的优势在于他的并行-Parallel Streams ,我们可以让流自己进行并行控制,而不用我们自己进行操作线程,这样就减少了很多很多的代码工作量,并且在绝大多数情况下,parallelStream应该也比自己操作线程效率要高的。但是也有不少的特殊情况,使用并行流反而会效率更低 ,这些情况基本上都是因为数据结构/装箱拆箱的难易程度/数据量的多少等等。


更新:重新看了下这个一年前的文章,感觉当时自己还是太缺乏对于未知/不完全了解的尊重了,对于自己不那么了解东西妄下了定义,经过了一年的使用,stream在我的感觉里 ,他不仅仅是一个花哨的stream了,用stream写出来的代码一眼就可以让人望文生义,一看filter就知道我在过滤数组,一看map就知道在对里面的结构进行操作,一看sorted就知道我需要排序, 固然 我可以在filter中做别的操作,但是如果正常使用的话,能感觉得到他是天然亲和函数式编程的,每个操作都是函数。 如果一定要说缺点:我了解到Stream 中foreach遍历会有更大的开销,因为没有for那么底层;而且调试也太痛苦了!!!

Streams are often terser. The same example shows this. Terser isn’t always better, but if you can be terse and expressive at the same time, so much the better. Streams have a strong affinity with functions. Java 8 introduces lambdas and functional interfaces, which opens a whole toybox of powerful techniques. Streams provide the most convenient and natural way to apply functions to sequences of objects. Streams encourage less mutability. This is sort of related to the functional programming aspect — the kind of programs you write using streams tend to be the kind of programs where you don’t modify objects. Streams encourage looser coupling. Your stream-handling code doesn’t need to know the source of the stream, or its eventual terminating method. Streams can succinctly express quite sophisticated behaviour — https://stackoverflow.com/questions/44180101/in-java-what-are-the-advantages-of-streams-over-loops/44183051


https://zhuanlan.zhihu.com/p/21394743

更深度的内容这篇博客讲的很好哦↓

https://www.cnblogs.com/CarpenterLee/p/6550212.html

One Comment

yabanci 10 12 月, 2020 Reply

I conceive you have noted some very interesting points, regards for the post. Sybila Magnum Lindberg

发表回复

蒙ICP备2022000577号-1