平常開發中,小黑哥常常須要用到 Java 提供集合類完成各類需求。Java 集合類雖然很是強大實用,可是提供功能仍是有點薄弱。java
舉個例子,小黑哥最近接到一個需求,從輸入一個文檔中,統計一個關鍵詞出現的次數。代碼以下:git
雖然這個需求使用 Map
能夠輕鬆搞定,可是小黑哥仍是以爲這種寫法有點笨拙,若是沒有判空,將會致使 NPE 異常。github
若是不少地方須要功能,咱們就能夠抽象出來,將其封裝成工具類。編程
不過上面的功能你們就不須要本身封裝,一款來自 Google 開源工具類-Guava,能夠輕鬆的解決上面的統計問題。緩存
Guava 是一款 Google 開源工具類,包含許多 Google 內部 Java
項目依賴的核心類。Guava 擴展 Java 基礎類工程,好比集合,併發等,也增長一些其餘強大功能,好比緩存,限流等功能。安全
另外 Guava 推出一些類,如 Optional
,甚至被 Java 開發者學習,後續增長到 JDK 中。多線程
目前 Guava Github 倉庫已有 36k star,能夠見到 Guava 受歡迎程度。併發
Guava 核心功能包括多個模塊,今天小黑哥主要帶你們玩轉 Guava 集合類。框架
Guava 創造不少 JDK 沒有,可是咱們平常卻明顯有用的新集合類型。這些新類型使用 JDK 集合接口規範,因此使用方法與 JDK 集合框架差很少,並無增長不少使用難度。ide
小黑哥第一次見到 Multiset
這個類,還覺得是 Set
接口子類。實際上此『Set』,僅僅只是數學上集合概念。
Multiset
繼承 JDK Collection
接口,咱們能夠屢次增長相同的元素,另外 Multiset
最大特定將會爲元素計數,咱們能夠將它相似等同爲 Map<E, Integer>
。
使用 Multiset
能夠輕鬆解決開頭的問題。
使用 Multiset
簡化了代碼,而且不再用擔憂新 NPE 的問題。
跟 JDK 集合類同樣,Multiset
也有許多子類。
這裏小黑哥提醒一下你們,雖然上面說過咱們能夠將 Multiset<E>
看作 Map<E, Integer>
,可是 Multiset
可不是 Map
的子類,它但是 血統純正的 Collection
子類。
小黑哥有時會在業務需求中使用 Map<String,List<Integer>
實現下面的需求。
a->[1,2,3] b->4,c->[6,5]
使用 Map
+ List
這種結構比較笨拙,而且代碼實現也比較繁瑣。Multimap
正式 Guava 中解決這種問題的新出的一個雷。
使用 Multimap
實現代碼以下:
這裏小黑哥使用 Multimap
子類 HashMultimap
,其行爲相似爲 Map<K,Set<V>>
,也就是說 Value
對應的集合內部元素不能重複。若是須要保存的重複的元素咱們可使用 ArrayListMultimap
。
Multimap
還有其餘子類,如圖所示:
BiMap
能夠用來實現鍵值對的雙向映射需求,這樣咱們就能夠經過 Key
查找對對應的 Value
,也可使用 Value
查找對應的 Key
。
這個需求若是使用 Map
實現,咱們就不得不使用兩個 Map
,維護雙向關係,而且任何改動還要保持同步。
使用 BiMap
修改上面的代碼:
這裏須要注意,BiMap#put
方法不能加入重複元素, 若加入,將會拋錯。若是若特定值必定要替換,可使用 BiMap#forcePut
代替。
敲黑板,這個知識點記下來。小黑哥使用過程當中,就踩過這個坑。
一樣的 BiMap
也有各類實現類:
Guava 另外還提供其餘集合類,不過這些類使用起來有點複雜,小黑哥還未在業務代碼中使用過,這裏簡單提下,感興趣同窗能夠深刻了解一下。
除了上面提到的新集合類之外,Guava 提供通用的工具類:
這些工具類需對使用的方法,咱們能夠快速建立集合,分割集合,轉化集合等。
使用工具類,咱們能夠快速建立集合。例如:
List<String> list=Lists.newArrayList(); Set<String> set=Sets.newHashSet(); Map<String,String> map=Maps.newHashMap();
相比於 new
集合方法,Guava 方法建立方式更加簡單。
List<String> list=new ArrayList<String>(); Set<String> set=new HashSet<String>(); Map<String,String> map=new HashMap<String, String>();
Guava 工具類智能推導 List
泛型,不再用兩側都重複寫泛型了。
另外還能夠指定集合類的初始化大小。
Lists#transform
方法能夠替代繁瑣 for
循環,將元素轉化,建立一個新集合類。
不過使用這個方法咱們要注意一點。
Lists#transform
內部使用懶加載的機制,只有在調用獲取的元素的時候,如 result.get
纔會真正使用 Function
從源 List
獲取元素,作相應的轉化。每次獲取元素都將會使用 function
進行轉化。
因此使用 Lists#transform
獲得 List
僅僅只是源 List
一個視圖,任何對源 List
的元素修改,都將會被反應到建立以後的 List
。任何對建立以後 List 中的元素進行修改,都不會生效。下次再次讀取元素時,將會發現相應修改的丟失了。。。
小黑哥以前就踩過這個坑,若是你有這種需求,可使用如下方式建立一個新集合:
JDK8 以前版本,小黑哥常用該方法轉化
List
中的元素。不過你若是使用 JDK8,小黑哥仍是推薦使用 Stream 流式編程。
Sets
提供幾個方法,能夠快速求出兩個 Set
集合的交集,並集以及差集。
不可變(Immutable)集合,顧名思義集合不能夠被修改。初始建立不可變集合時嗎,須要傳入數據源,建立完成以後,集合就不再能修改,增長,刪除元素,不然將會報錯。
這是一種防護性策略,防止集合在後續操做中被修改,從而引起問題。
不可變集合優勢在於:
Guava 不可變集合支持 JDK 全部集合接口:
咱們可使用以下幾種方式建立不可變集合,以 ImmutableList
爲例:
List<String> fromList=Lists.newArrayList("點贊","關注"); // 從一個集合拷貝元素 ImmutableList.copyOf(fromList); ImmutableList.of("關注","Java極客技術"); ImmutableList.builder().add("關注").addAll(fromList).build();
這篇文章小黑哥帶你們學習開源工具 Guava 集合的相關類使用方法,平常開發中咱們善於使用這些工具類,不要本身重複造輪子。
本篇文章僅僅只是介紹 Guava 一小部分功能,還有很對功能,小黑哥也以爲很好用在。這裏推薦你們去查看 Guava 官方 wiki,查看具體使用方法。
若是你們還想知道其餘開源工具類,給小黑哥點個贊,下次給你們帶來十分好用開源工具類~
歡迎關注個人公衆號:程序通事,得到平常乾貨推送。若是您對個人專題內容感興趣,也能夠關注個人博客: studyidea.cn