當前位置: 妍妍網 > 碼農

少寫無用程式碼,Guava 工具包簡直編程神器!

2024-04-27碼農

來源:jianshu.com/p/97778b21bd00

👉 歡迎 ,你將獲得: 專屬的計畫實戰 / Java 學習路線 / 一對一提問 / 學習打卡 / 贈書福利

全棧前後端分離部落格計畫 2.0 版本完結啦, 演示連結 http://116.62.199.48/ 新計畫正在醞釀中 。全程手摸手,後端 + 前端全棧開發,從 0 到 1 講解每個功能點開發步驟,1v1 答疑,直到計畫上線。 目前已更新了239小節,累計38w+字,講解圖:1645張,還在持續爆肝中.. 後續還會上新更多計畫,目標是將Java領域典型的計畫都整一波,如秒殺系統, 線上商城, IM即時通訊,Spring Cloud Alibaba 等等,

  • 以物件導向思想處理字串:Joiner/Splitter/CharMatcher

  • 對基本型別進行支持

  • 對JDK集合的有效補充

  • 函數語言程式設計:Functions

  • 斷言:Predicate

  • check null and other:Optional、Preconditions

  • Cache is king

  • 讓異步回呼更加簡單

  • Summary

  • 阿裏巴巴出了一本Java規範,在國內Java開發眼裏被賦予了神聖的殿堂,但是我司禁止使用阿裏巴巴的開發手冊。

    目前Google Guava在實際套用中非常廣泛,本篇部落格將以博主對Guava使用的認識以及在計畫中的經驗來給大家分享!正如標題所言,學習使用Google Guava可以讓你快樂編程,寫出優雅的JAVA程式碼!

    以物件導向思想處理字串:Joiner/Splitter/CharMatcher

    JDK提供的String還不夠好麽?

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

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

    那麽,看下面的程式碼範例,guava讓你不必在操心這些:

    Joiner/Splitter

    Joiner是連結器,Splitter是分割器,通常我們會把它們定義為static final,利用on生成物件後在套用到String進行處理,這是可以復用的。要知道apache commons StringUtils提供的都是static method。更加重要的是,guava提供的Joiner/Splitter是經過充分測試,它的穩定性和效率要比apache高出不少,這個你可以自行測試下~

    發現沒有我們想對String做什麽操作,就是生成自己客製化的Joiner/Splitter,多麽直白,簡單,流暢的API!

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

    對於Splitter,常用的方法是:trimResults()/omitEmptyStrings()。註意拆分的方式,有字串,還有正則,還有固定長度分割(太貼心了!)

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

    CharMatcher

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

    對基本型別進行支持

    guava對JDK提供的原生型別操作進行了擴充套件,使得功能更加強大!

    Ints

    guava提供了Bytes/Shorts/Ints/Iongs/Floats/Doubles/Chars/Booleans這些基本數據型別的延伸支援,只有你想不到的,沒有它沒有的!

    對JDK集合的有效補充

    灰色地帶:Multiset

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

    Multiset

    Multiset是什麽,我想上面的圖,你應該了解它的概念了。Multiset就是無序的,但是可以重復的集合,它就是遊離在List/Set之間的「灰色地帶」!(至於有序的,不允許重復的集合嘛,guava還沒有提供,當然在未來應該會提供UniqueList,我猜的,哈哈)

    來看一個Multiset的範例:

    Multiset Code

    Multiset內建一個有用的功能,就是可以跟蹤每個物件的數量。

    Immutable vs unmodifiable

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

    unmodifiable

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

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

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

    當然,在不使用guava的情況下,我們是怎麽避免上面的問題的呢?

    defensive copies

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

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

    Immutable

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

    用Google官方的說法是:we're using just one class,just say exactly what we mean,很了不起嗎(不僅僅是個概念,Immutable在COPY階段還考慮了執行緒的並行性等,很智慧的!),O(∩_∩)O哈哈~

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

    看一個ImmutableMap的例子:

    ImmutableMap

    可不可以一對多:Multimap

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

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

    Multimap

    友情提示下,guava所有的集合都有create方法,這樣的好處在於簡單,而且我們不必在重復泛型資訊了。

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

    Multimap的實作類有:ArrayListMultimap/HashMultimap/LinkedHashMultimap/TreeMultimap/ImmutableMultimap/......

    可不可以雙向:BiMap

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

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

    BiMap

    biMap / biMap.inverse() / biMap.inverse().inverse() 它們是什麽關系呢?

    你可以稍微看一下BiMap的源碼實作,實際上,當你建立BiMap的時候,在內部維護了2個map,一個forward map,一個backward map,並且設定了它們之間的關系。

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

    可不可以多個KEY:Table

    我們知道資料庫除了主鍵外,還提供了復合索引,而且實際中這樣的多級關系尋找也是比較多的,當然我們可以利用巢狀的Map來實作:Map<k1,Map<k2,v2>>。為了讓我們的程式碼看起來不那麽醜陋,guava為我們提供了Table。

    Table

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

    函數語言程式設計:Functions

    Functions

    上面的程式碼是為了完成將List集合中的元素,先截取5個長度,然後轉成大寫。

    函數語言程式設計的好處在於在集合遍歷操作中提供自訂Function的操作,比如transform轉換。我們再也不需要一遍遍的遍歷集合,顯著的簡化了程式碼!

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

    斷言:Predicate

    圖片

    Predicate最常用的功能就是運用在集合的過濾當中!

    filter

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

    check null and other:Optional、Preconditions

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

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

    Preconditions/Optional

    Cache is king

    對於大多數互聯網計畫而言,緩存的重要性,不言而喻!

    如果我們的套用系統,並不想使用一些第三方緩存元件(如redis),我們僅僅想在本地有一個功能足夠強大的緩存,很可惜JDK提供的那些SET/MAP還不行!

    CacheLoader

    首先,這是一個本地緩存,guava提供的cache是一個簡潔、高效,易於維護的。為什麽這麽說呢?因為並沒有一個單獨的執行緒用於重新整理 OR 清理cache,對於cache的操作,都是透過存取/讀寫帶來的,也就是說在讀寫中完成緩存的重新整理操作!

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

    讓異步回呼更加簡單

    JDK中提供了Future/FutureTask/Callable來對異步回呼進行支持,但是還是看上去挺復雜的,能不能更加簡單呢?比如註冊一個監聽回呼。

    異步回呼

    我們可以透過guava對JDK提供的執行緒池進行裝飾,讓其具有異步回呼監聽功能,然後在設定監聽器即可!

    Summary

    到這裏,這篇文章也只介紹了guava的冰山一角,其實還有很多內容:

    圖片

    guava package

    比如反射、註解、網路、並行、IO等等

    好了,希望這篇文章讓你快速進階,快樂編程!

    👉 歡迎 ,你將獲得: 專屬的計畫實戰 / Java 學習路線 / 一對一提問 / 學習打卡 / 贈書福利

    全棧前後端分離部落格計畫 2.0 版本完結啦, 演示連結 http://116.62.199.48/ 新計畫正在醞釀中 。全程手摸手,後端 + 前端全棧開發,從 0 到 1 講解每個功能點開發步驟,1v1 答疑,直到計畫上線。 目前已更新了239小節,累計38w+字,講解圖:1645張,還在持續爆肝中.. 後續還會上新更多計畫,目標是將Java領域典型的計畫都整一波,如秒殺系統, 線上商城, IM即時通訊,Spring Cloud Alibaba 等等,


    1. 

    2. 

    3. 

    4. 

    最近面試BAT,整理一份面試資料Java面試BATJ通關手冊,覆蓋了Java核心技術、JVM、Java並行、SSM、微服務、資料庫、數據結構等等。

    獲取方式:點「在看」,關註公眾號並回復 Java 領取,更多內容陸續奉上。

    PS:因公眾號平台更改了推播規則,如果不想錯過內容,記得讀完點一下在看,加個星標,這樣每次新文章推播才會第一時間出現在你的訂閱列表裏。

    「在看」支持小哈呀,謝謝啦