真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

學(xué)習(xí)Java8的Stream

??Stream把對一個集合的很多操作,以一種流式作業(yè)串起來,按照類似函數(shù)式編程書寫代碼,界面清爽清晰。
?Stream不同于Guava的FluentIterable系列。FluentIterable系列,是通過封裝集合(List、Set等)并且重載迭代器、get的方式,進行的transform、filter等,優(yōu)點是簡單并且性能高。缺點是功能單一、并且容易誤用。比如,對transform之后的列表的每個項,本質(zhì)上都是一個視圖(View),而不是實際的項(值對象)。多次調(diào)用get方法。這本質(zhì)上每次都會層層調(diào)用Function的apply方法,如果其中有復(fù)雜運算或者I/O讀取,效率是非常低的。
  Stream本身,建立了一系列的數(shù)據(jù)結(jié)構(gòu),其中的數(shù)據(jù)都可以看成是實際存在的數(shù)據(jù),而并不僅僅是視圖。網(wǎng)上分析源代碼的文章非常多,這里不重復(fù)描述,而是僅僅介紹理解的一個思路。
?首先,是幾個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)。
?Stream。接口是BaseStream,可以看做是流基本『形態(tài)』的描述?;蛘哒f,每個流式作業(yè)。雖然后面提到的Pipeline也是實現(xiàn)了BaseStream,但是這樣似乎更容易理解。
?Pipeline。公共父類是AbstractPipeline??梢钥醋鍪橇魇阶鳂I(yè)中的每個作業(yè),或者說是每個作業(yè)節(jié)點。為了防止不必要的裝箱和拆箱操作,又分成了ReferencePipeline、IntPipeline、LongPipeline、DoublePipeline。這些管道可以分成三種:頭、終結(jié)操作、非終結(jié)操作。分別對應(yīng)的類是XXXXPipeline.Head、XXXXPipeline.StatelessOp和XXXXPipeline.StatefulOp、TerminalOp.調(diào)用流的工作方法,都會制造出來這樣一個Pipeline。比如,調(diào)用IntStream.of(),就會生成一個頭;調(diào)用Stream.map(),會生成一個非終結(jié)操作;調(diào)用Stream.reduce(),生成一個終結(jié)操作。非終結(jié)操作里面,都要實現(xiàn)opWrapSink方法,該方法要返回一個Sink。
?Sink。每個操作,對應(yīng)一個Sink。每個Sink,關(guān)注三個方法:begin、end、accept。如果當前的Sink沒有操作,那么直接調(diào)用downstream.accept;否則,把當前操作結(jié)果作為參數(shù)調(diào)用downstream.accept。downstream是什么概念呢?比如,一個流的操作是IntStream.of(1,2,3).map(x -> x + 1).boxed().max()。那么map對應(yīng)的sink,就是頭的downstream,boxed對應(yīng)的sink就是map的downstream。綜合起來,只要調(diào)用了頭的accept,就會層層調(diào)用到最后一個終結(jié)操作。終結(jié)操作沒有opWrapSink方法,所以自然不會調(diào)用到后續(xù)的流。
?Spliterator。流里面數(shù)據(jù)的訪問工具。如果是串行流,一般是直接調(diào)用里面的forEachRemaining。該方法里關(guān)注action.accept,如果之前串聯(lián)好了每個Sink,那么這里一句調(diào)用,就開始了Sink的層層調(diào)用。
?至此,基本數(shù)據(jù)結(jié)構(gòu)就介紹這些。下面,關(guān)注流的每個節(jié)點,是如何連起來的。
?每個Stream,由一組Pipeline節(jié)點組成,每追加一個操作,都會向這組Pipeline后面追加一個Pipeline結(jié)構(gòu)。追加時候維護的信息里面,關(guān)注sourceStage(頭),previousStage(上一個Pipeline),sourceSupplier(流數(shù)據(jù)的Spliterator),depth(Pipeline長度)。一直到最后的終結(jié)操作,連城一個Pipeline鏈。
?對于終結(jié)操作,不論是reduce,還是collect操作,都會調(diào)用到AbstracePipeline.evaluate方法。以串行流的reduce為例,直接調(diào)用到AbstractPipeline.wrapAndCopyInto。
?其中,wrap是遍歷Pipeline鏈,調(diào)用每個階段的opWrapSink。這樣每個Sink通過方法逐層調(diào)用(而非內(nèi)存數(shù)據(jù)上的指針鏈接),從第一個Pipeline的Sink鏈接到末尾。

創(chuàng)新互聯(lián)服務(wù)項目包括雁江網(wǎng)站建設(shè)、雁江網(wǎng)站制作、雁江網(wǎng)頁制作以及雁江網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,雁江網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到雁江省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

    @Override
    @SuppressWarnings("unchecked")
    final  Sink wrapSink(Sink sink) {
        Objects.requireNonNull(sink);

        for ( @SuppressWarnings("rawtypes") AbstractPipeline p=AbstractPipeline.this; p.depth > 0; p=p.previousStage) {
            sink = p.opWrapSink(p.previousStage.combinedFlags, sink);
        }
        return (Sink) sink;
    }

??copyInto是依次調(diào)用Sink.begin,Spliterator.forEachRemaing,Sink.end方法。上文曾經(jīng)提到,forEachRemaing會以流里的每項數(shù)據(jù)為參數(shù),層層調(diào)用每級Sink的accept。

    @Override
    final  void copyInto(Sink wrappedSink, Spliterator spliterator) {
        Objects.requireNonNull(wrappedSink);

        if (!StreamOpFlag.SHORT_CIRCUIT.isKnown(getStreamAndOpFlags())) {
            wrappedSink.begin(spliterator.getExactSizeIfKnown());
            spliterator.forEachRemaining(wrappedSink);
            wrappedSink.end();
        }
        else {
            copyIntoWithCancel(wrappedSink, spliterator);
        }
    }

??至此,整個流的操作,自上而下完全聯(lián)系到了一起。
?


網(wǎng)頁題目:學(xué)習(xí)Java8的Stream
地址分享:http://weahome.cn/article/jdpgce.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部