1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        用 Google Guava 編程強(qiáng)過阿里巴巴規(guī)范?

        共 4682字,需瀏覽 10分鐘

         ·

        2021-07-05 10:11

        不點藍(lán)字,我們哪來故事?

        每天 11 點更新文章,餓了點外賣,點擊 ??《無門檻外賣優(yōu)惠券,每天免費(fèi)領(lǐng)!》

        來源:jianshu.com/p/97778b21bd00

        • 以面向?qū)ο笏枷胩幚碜址?Joiner/Splitter/CharMatcher
        • 對基本類型進(jìn)行支持
        • 對JDK集合的有效補(bǔ)充
        • 函數(shù)式編程:Functions
        • 斷言:Predicate
        • check null and other:Optional、Preconditions
        • Cache is king
        • 讓異步回調(diào)更加簡單
        • Summary

        目前Google Guava在實際應(yīng)用中非常廣泛,本篇博客將以博主對Guava使用的認(rèn)識以及在項目中的經(jīng)驗來給大家分享!正如標(biāo)題所言,學(xué)習(xí)使用Google Guava可以讓你快樂編程,寫出優(yōu)雅的JAVA代碼!

        以面向?qū)ο笏枷胩幚碜址?Joiner/Splitter/CharMatcher

        JDK提供的String還不夠好么?

        也許還不夠友好,至少讓我們用起來還不夠爽,還得操心!

        舉個栗子,比如String提供的split方法,我們得關(guān)心空字符串吧,還得考慮返回的結(jié)果中存在null元素吧,只提供了前后trim的方法(如果我想對中間元素進(jìn)行trim呢)。

        那么,看下面的代碼示例,guava讓你不必在操心這些:

        Joiner/Splitter

        Joiner是連接器,Splitter是分割器,通常我們會把它們定義為static final,利用on生成對象后在應(yīng)用到String進(jìn)行處理,這是可以復(fù)用的。要知道apache commons StringUtils提供的都是static method。更加重要的是,guava提供的Joiner/Splitter是經(jīng)過充分測試,它的穩(wěn)定性和效率要比apache高出不少,這個你可以自行測試下~

        發(fā)現(xiàn)沒有我們想對String做什么操作,就是生成自己定制化的Joiner/Splitter,多么直白,簡單,流暢的API!

        對于Joiner,常用的方法是  跳過NULL元素:skipNulls()  /  對于NULL元素使用其他替代:useForNull(String)

        對于Splitter,常用的方法是:trimResults()/omitEmptyStrings()。注意拆分的方式,有字符串,還有正則,還有固定長度分割(太貼心了?。?/strong>

        其實除了Joiner/Splitter外,guava還提供了字符串匹配器:CharMatcher

        CharMatcher

        CharMatcher,將字符的匹配和處理解耦,并提供豐富的方法供你使用!

        對基本類型進(jìn)行支持

        guava對JDK提供的原生類型操作進(jìn)行了擴(kuò)展,使得功能更加強(qiáng)大!

        Ints

        guava提供了Bytes/Shorts/Ints/Iongs/Floats/Doubles/Chars/Booleans這些基本數(shù)據(jù)類型的擴(kuò)展支持,只有你想不到的,沒有它沒有的!

        對JDK集合的有效補(bǔ)充

        灰色地帶:Multiset

        JDK的集合,提供了有序且可以重復(fù)的List,無序且不可以重復(fù)的Set。那這里其實對于集合涉及到了2個概念,一個order,一個dups。那么List vs Set,and then some ?

        Multiset

        Multiset是什么,我想上面的圖,你應(yīng)該了解它的概念了。Multiset就是無序的,但是可以重復(fù)的集合,它就是游離在List/Set之間的“灰色地帶”!

        (至于有序的,不允許重復(fù)的集合嘛,guava還沒有提供,當(dāng)然在未來應(yīng)該會提供UniqueList,我猜的,哈哈)

        來看一個Multiset的示例:

        Multiset Code

        Multiset自帶一個有用的功能,就是可以跟蹤每個對象的數(shù)量。

        Immutable vs unmodifiable

        來我們先看一個unmodifiable的例子:

        unmodifiable

        你看到JDK提供的unmodifiable的缺陷了嗎?

        實際上,Collections.unmodifiableXxx所返回的集合和源集合是同一個對象,只不過可以對集合做出改變的API都被override,會拋出UnsupportedOperationException。

        也即是說我們改變源集合,導(dǎo)致不可變視圖(unmodifiable View)也會發(fā)生變化,oh my god!

        當(dāng)然,在不使用guava的情況下,我們是怎么避免上面的問題的呢?

        defensive copies

        上面揭示了一個概念:Defensive Copies,保護(hù)性拷貝。

        OK,unmodifiable看上去沒有問題呢,但是guava依然覺得可以改進(jìn),于是提出了Immutable的概念,來看:

        Immutable

        就一個copyOf,你不會忘記,如此cheap~

        用Google官方的說法是:we're using just one class,just say exactly what we mean,很了不起嗎(不僅僅是個概念,Immutable在COPY階段還考慮了線程的并發(fā)性等,很智能的?。琌(∩_∩)O哈哈~

        guava提供了很多Immutable集合,比如ImmutableList/ImmutableSet/ImmutableSortedSet/ImmutableMap/......

        看一個ImmutableMap的例子:

        ImmutableMap

        可不可以一對多:Multimap

        JDK提供給我們的Map是一個鍵,一個值,一對一的,那么在實際開發(fā)中,顯然存在一個KEY多個VALUE的情況(比如一個分類下的書本),我們往往這樣表達(dá):Map<k,List>,好像有點臃腫!臃腫也就算了,更加不爽的事,我們還得判斷KEY是否存在來決定是否new 一個LIST出來,有點麻煩!更加麻煩的事情還在后頭,比如遍歷,比如刪除,so hard......

        來看guava如何替你解決這個大麻煩的:

        Multimap

        友情提示下,guava所有的集合都有create方法,這樣的好處在于簡單,而且我們不必在重復(fù)泛型信息了。

        get()/keys()/keySet()/values()/entries()/asMap()都是非常有用的返回view collection的方法。

        Multimap的實現(xiàn)類有:ArrayListMultimap/HashMultimap/LinkedHashMultimap/TreeMultimap/ImmutableMultimap/......

        可不可以雙向:BiMap

        JDK提供的MAP讓我們可以find value by key,那么能不能通過find key by value呢,能不能KEY和VALUE都是唯一的呢。這是一個雙向的概念,即forward+backward。

        在實際場景中有這樣的需求嗎?比如通過用戶ID找到mail,也需要通過mail找回用戶名。沒有g(shù)uava的時候,我們需要create forward map AND create backward map,and now just let guava do that for you.

        BiMap

        biMap / biMap.inverse() / biMap.inverse().inverse() 它們是什么關(guān)系呢?

        你可以稍微看一下BiMap的源碼實現(xiàn),實際上,當(dāng)你創(chuàng)建BiMap的時候,在內(nèi)部維護(hù)了2個map,一個forward map,一個backward map,并且設(shè)置了它們之間的關(guān)系。

        因此,biMap.inverse()  != biMap ;biMap.inverse().inverse() == biMap

        可不可以多個KEY:Table

        我們知道數(shù)據(jù)庫除了主鍵外,還提供了復(fù)合索引,而且實際中這樣的多級關(guān)系查找也是比較多的,當(dāng)然我們可以利用嵌套的Map來實現(xiàn):Map<k1,Map<k2,v2>>。為了讓我們的代碼看起來不那么丑陋,guava為我們提供了Table。

        Table

        Table涉及到3個概念:rowKey,columnKey,value,并提供了多種視圖以及操作方法讓你更加輕松的處理多個KEY的場景。

        函數(shù)式編程:Functions

        Functions

        上面的代碼是為了完成將List集合中的元素,先截取5個長度,然后轉(zhuǎn)成大寫。

        函數(shù)式編程的好處在于在集合遍歷操作中提供自定義Function的操作,比如transform轉(zhuǎn)換。我們再也不需要一遍遍的遍歷集合,顯著的簡化了代碼!

        對集合的transform操作可以通過Function完成

        斷言:Predicate

        Predicate最常用的功能就是運(yùn)用在集合的過濾當(dāng)中!

        filter

        需要注意的是Lists并沒有提供filter方法,不過你可以使用Collections2.filter完成!

        check null and other:Optional、Preconditions

        在guava中,對于null的處理手段是快速失敗,你可以看看guava的源碼,很多方法的第一行就是:Preconditions.checkNotNull(elements);

        要知道null是模糊的概念,是成功呢,還是失敗呢,還是別的什么含義呢?

        Preconditions/Optional

        Cache is king

        對于大多數(shù)互聯(lián)網(wǎng)項目而言,緩存的重要性,不言而喻!

        如果我們的應(yīng)用系統(tǒng),并不想使用一些第三方緩存組件(如redis),我們僅僅想在本地有一個功能足夠強(qiáng)大的緩存,很可惜JDK提供的那些SET/MAP還不行!

        CacheLoader

        首先,這是一個本地緩存,guava提供的cache是一個簡潔、高效,易于維護(hù)的。為什么這么說呢?因為并沒有一個單獨(dú)的線程用于刷新 OR 清理cache,對于cache的操作,都是通過訪問/讀寫帶來的,也就是說在讀寫中完成緩存的刷新操作!

        其次,我們看到了,我們非常通俗的告訴cache,我們的緩存策略是什么,SO EASY!在如此簡單的背后,是guava幫助我們做了很多事情,比如線程安全。

        讓異步回調(diào)更加簡單

        JDK中提供了Future/FutureTask/Callable來對異步回調(diào)進(jìn)行支持,但是還是看上去挺復(fù)雜的,能不能更加簡單呢?比如注冊一個監(jiān)聽回調(diào)。

        異步回調(diào)

        我們可以通過guava對JDK提供的線程池進(jìn)行裝飾,讓其具有異步回調(diào)監(jiān)聽功能,然后在設(shè)置監(jiān)聽器即可!

        Summary

        到這里,這篇文章也只介紹了guava的冰山一角,其實還有很多內(nèi)容:

        guava package

        比如反射、注解、網(wǎng)絡(luò)、并發(fā)、IO等等

        好了,希望這篇文章讓你快速進(jìn)階,快樂編程!

        - END -

        往期推薦

        為取消大小周而歡呼?字節(jié)員工可不那么想...

        Exception經(jīng)驗之談,萬萬沒想到被很多團(tuán)隊采納!

        美團(tuán)面試:JVM 堆內(nèi)存溢出后,其他線程是否可繼續(xù)工作?

        圖解 Spring 循環(huán)依賴!

        下方二維碼關(guān)注我

        技術(shù)草根堅持分享 編程,算法,架構(gòu)

        看完文章,餓了點外賣,點擊 ??《無門檻外賣優(yōu)惠券,每天免費(fèi)領(lǐng)!》

        朋友,助攻一把!點個在看!
        瀏覽 87
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

          <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久久免费福利 | 欧美三级电影院 | 2025国产成人精品一区 | 九狐男女视频诱惑在线观看 | www.超碰在线.com | 欧美美女性高潮 | 国产乱伦性爱电影。 | 国产无套粉嫩 | 精品国产一区二区三区蜜殿 | 国产欧美精品在线观看 |