<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么強(qiáng)烈推薦 Java 程序員使用 Google Guava 編程!

          共 4362字,需瀏覽 9分鐘

           ·

          2020-12-22 14:24

          注:由于公眾號(hào)文章推送規(guī)則改變,所以為了大家能夠準(zhǔn)時(shí)收到我們的文章推送,請(qǐng)記得將公眾號(hào):?JAVA?設(shè)為星標(biāo)~這樣就不會(huì)錯(cuò)過(guò)每一篇精彩的推送啦~

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

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

          JDK提供的String還不夠好么?

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

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

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

          Joiner/Splitter

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

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

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

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

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

          CharMatcher

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

          對(duì)基本類(lèi)型進(jìn)行支持

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


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

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

          灰色地帶:Multiset

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


          Multiset是什么,我想上面的圖,你應(yīng)該了解它的概念了。Multiset就是無(wú)序的,但是可以重復(fù)的集合,它就是游離在List/Set之間的“灰色地帶”?。ㄖ劣谟行虻?,不允許重復(fù)的集合嘛,guava還沒(méi)有提供,當(dāng)然在未來(lái)應(yīng)該會(huì)提供UniqueList,我猜的,哈哈)

          來(lái)看一個(gè)Multiset的示例:


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

          Immutable vs unmodifiable

          來(lái)我們先看一個(gè)unmodifiable的例子:


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

          實(shí)際上,Collections.unmodifiableXxx所返回的集合和源集合是同一個(gè)對(duì)象,只不過(guò)可以對(duì)集合做出改變的API都被override,會(huì)拋出UnsupportedOperationException。

          也即是說(shuō)我們改變?cè)醇?,?dǎo)致不可變視圖(unmodifiable View)也會(huì)發(fā)生變化,oh my god!

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


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

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


          就一個(gè)copyOf,你不會(huì)忘記,如此cheap~

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

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

          看一個(gè)ImmutableMap的例子:

          可不可以一對(duì)多:Multimap

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

          來(lái)看guava如何替你解決這個(gè)大麻煩的:


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

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

          Multimap的實(shí)現(xiàn)類(lèi)有:ArrayListMultimap/HashMultimap/LinkedHashMultimap/TreeMultimap/ImmutableMultimap/......

          可不可以雙向:BiMap

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

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


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

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

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

          可不可以多個(gè)KEY:Table 關(guān)注公眾號(hào):JAVA獲取更多干貨文章

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


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

          函數(shù)式編程:Functions


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

          函數(shù)式編程的好處在于在集合遍歷操作中提供自定義Function的操作,比如transform轉(zhuǎn)換。我們?cè)僖膊恍枰槐楸榈谋闅v集合,顯著的簡(jiǎn)化了代碼!

          對(duì)集合的transform操作可以通過(guò)Function完成

          斷言:Predicate

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


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


          check null and other:Optional、Preconditions

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

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

          Cache is king

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

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


          首先,這是一個(gè)本地緩存,guava提供的cache是一個(gè)簡(jiǎn)潔、高效,易于維護(hù)的。為什么這么說(shuō)呢?因?yàn)椴](méi)有一個(gè)單獨(dú)的線(xiàn)程用于刷新 OR 清理cache,對(duì)于cache的操作,都是通過(guò)訪(fǎng)問(wèn)/讀寫(xiě)帶來(lái)的,也就是說(shuō)在讀寫(xiě)中完成緩存的刷新操作!

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

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

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


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

          Summary

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


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

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

          作者:張豐哲?

          鏈接:https://www.jianshu.com/p/97778b21bd00

          最近熬夜給大家準(zhǔn)備了515套Java代碼,有一些是業(yè)務(wù)類(lèi)的小項(xiàng)目,比如Java博客項(xiàng)目,也有腳手架、也有平時(shí)用一些的工具類(lèi)、21套小程序代碼,也有一些游戲類(lèi)的項(xiàng)目。

          掃以下二維碼并回復(fù)“828”即可獲取


          或者在本公眾號(hào)對(duì)話(huà)框回復(fù)【828】馬上獲取

          瀏覽 48
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费区欧美一级毛片99宜春院 | 国产一卡二卡三卡免费观看 | 日本AA片视频 | 91无码精品秘 入口 | 亚洲一级黄色视频网站 |