Guava介紹 – Google的Java常用類庫

Guava的前身是Google Collections,

是Google開源出來的一個Java常用類庫,包含了一些集合的便捷操作API。從Google Collections進化到Guava後,對常用的字符串操作、文件操作、網絡操作、多線程併發操作提供了很方便的API,當然重頭戲還是集合部分,下面會用一些例子來梳理一下Guava的常用API。

Guava目前的版本(release 09)主要分這麼幾個包:

com.google.common.base

com.google.common.annotations

com.google.common.primitives

com.google.common.io

com.google.common.net

com.google.common.collect

com.google.common.util.concurrent

先從com.google.common.base說起,說白了,這個包下的類,就是對原生的java.lang下的類進行一些增強,很多常用的操作,省的自己寫冗餘代碼了,Guava直接給你提供現成的了。

最常用的:Strings.isNullOrEmpty(…),呵呵,雖然沒啥技術含量,但是用慣了JavaScript、PHP之類的動態語言,對Java原本那種囉嗦的寫法真是越看越不順眼。。。

再比如字符串匹配操作:CharMatcher.anyOf(“aeiou”).countIn(“This is a test!”); // 元音字母計數,用for循環寫得拖沓很多了吧。

拼字符串:String s = Joiner.on(“,”).skipNulls().join(userIdArray); // 鏈式操作,簡單明瞭,如果用Java老老實實自己寫就得這樣了:

Guava介紹 – Google的Java常用類庫

孰優孰劣。。。再來個更強的:

String s = Joiner.on(“;”).withKeyValueSeparator(“|”).join(userIdNameMap); // 你一定遇上過這樣的需求,有一組用戶ID和用戶暱稱的對照表,要拼一個字符串,ID和暱稱之間用|分隔,每對記錄之間用;分隔,又是簡單一句鏈式操作搞定,自己寫又得雙層for循環咯。。。

與拼字符串相對應的還有拆字符串:Splitter.on(“|”).trimResults().omitEmptyStrings().split(” a,,b , c ,”); // 如你所願的會返回a、b、c這3個元素,可以去掉左右空白字符、忽略空字符串,自己寫又得for循環 + 一堆if/else了吧。。。

再來看看com.google.common.io包,主要包括文件操作和IO操作。原本的Java API,對IO操作有太多的裝飾者模式,一層套一層,還有各種Exception,得寫很多try..catch..finally,很煩躁。再來看看Guava提供的API:Files.touch(…) ,更新文件的時間戳;Files.deleteRecursively(…) ,遞歸刪除文件夾及裡面所有文件;List<string> Files.readLines(File, Charset) ,指定文件和字符集,把內容讀到一個List中;Files.append(CharSequence from, File to, Charset) ,把字符串用指定字符集追加到文件尾部。/<string>

想一想,手寫Java代碼需要多少工作:new一層又一層的InputStream、Reader,try..catch..finally,最噁心的是finally裡面還要再try..catch。

重頭戲來了,com.google.common.collect包,是對Java Collections的一次升級,附加了很多非常好用的API。

Guava新增了一個概念,叫做 不可變集合,ImmutableCollection,很多情況下,我們使用List、Map、Set,只是作為一種DTO,僅僅是傳輸數據,而它的size實際上在編碼時就是已知確定的,這時我們使用不可變集合,可以有更好的性能和更方便的API。比如說,用Hibernate時,HQL語句需要綁定變量:from Student s where s.name=:name and s.age>:age,我們需要傳一個Map作為參數,可以這樣:Map params = ImmutableMap.of(“name”, “zhangsan”, “age”, 20); 就得到了一個不可變Map對象。而用標準Java API,至少需要寫3行代碼。

原先需要new一個Map需要這麼寫:Map<string> aMap = new HashMap<string>(); 其實Java的泛型支持合理的類型推斷的,Guava就提供了這樣的API:Map<string> aMap = Maps.newHashMap(); // DRY – don’t repeat yourself! 而且還用不著@SuppressWarnings(“unchecked”),很方便,有Lists、Sets、Maps等工廠類。/<string>/<string>/<string>

非常實用的一個API:

MapDifference diff = Maps.difference(Map left, Map right); 之後可以調用

diff.entriesOnlyOnLeft() // 獲得只在左集合有的部分

diff.entriesOnlyOnRight() // 獲得只在右集合有的部分

diff.entriesInCommon() // 獲得交集部分

Guava新增了一個概念,叫做BiMap,雙向Map,比如說我需要一個Map,可以根據用戶ID找到用戶暱稱,還可以根據用戶暱稱查找用戶ID,這時就可以用到雙向Map了。

傳統的Set是保存不重複的元素的,而Guava有個Multiset,可以對每個元素進行計數,通俗點講,Multiset就相當於Map,每當對Multiset add一個元素,就對這個元素的計數值+1,一個元素可以添加多次。類似的還有Multimap,Multimap就相當於Map

>,每當put一對KV,就把V放到K對應的Collection中去,對於同一個Key,可以put多個不同的Value。

總結

可以說,Guava本身並沒有什麼高科技,它的實現都很好理解,大家也都能自己實現出來一個。但是它的API確實是太實用了,讓人有一種“對,我就是想要一個這樣的接口!”的感覺,用起來非常痛快,強烈推薦給所有Java開發者。

對於一個熟練的工程師來說,很多時候需要的不是神秘、高科技的重型工具,只是一把趁手的螺絲刀。


分享到:


相關文章: