目前Google Guava在實際應用中很是普遍,本篇博客將以博主對Guava使用的認識以及在項目中的經驗來給你們分享!正如標題所言,學習使用Google Guava可讓你快樂編程,寫出優雅的JAVA代碼!java
JDK提供的String還不夠好麼?面試
也許還不夠友好,至少讓咱們用起來還不夠爽,還得操心!redis
舉個栗子,好比String提供的split方法,咱們得關心空字符串吧,還得考慮返回的結果中存在null元素吧,只提供了先後trim的方法(若是我想對中間元素進行trim呢)。spring
那麼,看下面的代碼示例,guava讓你沒必要在操心這些:數據庫
Joiner是鏈接器,Splitter是分割器,一般咱們會把它們定義爲static final,利用on生成對象後在應用到String進行處理,這是能夠複用的。要知道apache commons StringUtils提供的都是static method。更加劇要的是,guava提供的Joiner/Splitter是通過充分測試,它的穩定性和效率要比apache高出很多,這個你能夠自行測試下~apache
發現沒有咱們想對String作什麼操做,就是生成本身定製化的Joiner/Splitter,多麼直白,簡單,流暢的API!編程
對於Joiner,經常使用的方法是 跳過NULL元素:skipNulls() / 對於NULL元素使用其餘替代:useForNull(String)緩存
對於Splitter,經常使用的方法是: trimResults()/omitEmptyStrings()。注意拆分的方式,有字符串,還有正則,還有固定長度分割(太貼心了!)安全
其實除了Joiner/Splitter外,guava還提供了字符串匹配器:CharMatcher網絡
CharMatcher,將字符的匹配和處理解耦,並提供豐富的方法供你使用!
guava對JDK提供的原生類型操做進行了擴展,使得功能更增強大!
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就是無序的,可是能夠重複的集合,它就是遊離在List/Set之間的「灰色地帶」!(至於有序的,不容許重複的集合嘛,guava尚未提供,固然在將來應該會提供UniqueList,我猜的,哈哈)
來看一個Multiset的示例:
Multiset自帶一個有用的功能,就是能夠跟蹤每一個對象的數量。
來咱們先看一個unmodifiable的例子:
你看到JDK提供的unmodifiable的缺陷了嗎?
實際上,Collections.unmodifiableXxx所返回的集合和源集合是同一個對象,只不過能夠對集合作出改變的API都被override,會拋出UnsupportedOperationException。
也便是說咱們改變源集合,致使不可變視圖(unmodifiable View)也會發生變化,oh my god!
固然,在不使用guava的狀況下,咱們是怎麼避免上面的問題的呢?
上面揭示了一個概念:Defensive Copies,保護性拷貝。
OK,unmodifiable看上去沒有問題呢,可是guava依然以爲能夠改進,因而提出了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的例子:
JDK提供給咱們的Map是一個鍵,一個值,一對一的,那麼在實際開發中,顯然存在一個KEY多個VALUE的狀況(好比一個分類下的書本),咱們每每這樣表達:Map<k,List<v>>,好像有點臃腫!臃腫也就算了,更加不爽的事,咱們還得判斷KEY是否存在來決定是否new 一個LIST出來,有點麻煩!更加麻煩的事情還在後頭,好比遍歷,好比刪除,so hard......
來看guava如何替你解決這個大麻煩的:
友情提示下,guava全部的集合都有create方法,這樣的好處在於簡單,並且咱們沒必要在重複泛型信息了。
get()/keys()/keySet()/values()/entries()/asMap()都是很是有用的返回view collection的方法。
Multimap的實現類有:ArrayListMultimap/HashMultimap/LinkedHashMultimap/TreeMultimap/ImmutableMultimap/......
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.inverse() / biMap.inverse().inverse() 它們是什麼關係呢?
你能夠稍微看一下BiMap的源碼實現,實際上,當你建立BiMap的時候,在內部維護了2個map,一個forward map,一個backward map,而且設置了它們之間的關係。
所以,biMap.inverse() != biMap ; biMap.inverse().inverse() == biMap
咱們知道數據庫除了主鍵外,還提供了複合索引,並且實際中這樣的多級關係查找也是比較多的,固然咱們能夠利用嵌套的Map來實現:Map<k1,Map<k2,v2>>。爲了讓咱們的代碼看起來不那麼醜陋,guava爲咱們提供了Table。
Table涉及到3個概念:rowKey,columnKey,value,並提供了多種視圖以及操做方法讓你更加輕鬆的處理多個KEY的場景。
上面的代碼是爲了完成將List集合中的元素,先截取5個長度,而後轉成大寫。
函數式編程的好處在於在集合遍歷操做中提供自定義Function的操做,好比transform轉換。咱們不再須要一遍遍的遍歷集合,顯著的簡化了代碼!
Predicate最經常使用的功能就是運用在集合的過濾當中!
須要注意的是Lists並無提供filter方法,不過你可使用Collections2.filter完成!
在guava中,對於null的處理手段是快速失敗,你能夠看看guava的源碼,不少方法的第一行就是:Preconditions.checkNotNull(elements);
要知道null是模糊的概念,是成功呢,仍是失敗呢,仍是別的什麼含義呢?
對於大多數互聯網項目而言,緩存的重要性,不言而喻!
若是咱們的應用系統,並不想使用一些第三方緩存組件(如redis),咱們僅僅想在本地有一個功能足夠強大的緩存,很惋惜JDK提供的那些SET/MAP還不行!
首先,這是一個本地緩存,guava提供的cache是一個簡潔、高效,易於維護的。爲何這麼說呢?由於並無一個單獨的線程用於刷新 OR 清理cache,對於cache的操做,都是經過訪問/讀寫帶來的,也就是說在讀寫中完成緩存的刷新操做!
其次,咱們看到了,咱們很是通俗的告訴cache,咱們的緩存策略是什麼,SO EASY!在如此簡單的背後,是guava幫助咱們作了不少事情,好比線程安全。
JDK中提供了Future/FutureTask/Callable來對異步回調進行支持,可是仍是看上去挺複雜的,能不能更加簡單呢?好比註冊一個監聽回調。
咱們能夠經過guava對JDK提供的線程池進行裝飾,讓其具備異步回調監聽功能,而後在設置監聽器便可!
到這裏,這篇文章也只介紹了guava的冰山一角,其實還有不少內容:
好比反射、註解、網絡、併發、IO等等
好了,但願這篇文章讓你快速進階,快樂編程!
工做一到五年的java 開發工程師朋友能夠加入咱們Java架構交流羣:760940986 羣內提供 高可用,高併發,spring源碼,mybatis源碼,JVM,大數據,Netty等多個技術知識的架構視頻資料 還有大把大牛在羣內交流以及解答面試指導,問題答疑~~要進來和大牛交流學習提高提高本身嗎~~~~