關於google-collections.jar

google collections是google的工程師利用傳說中的“20%時間”開發的集合庫,它是對java.util的擴展,提供了很多實用的類來簡化代碼。google collections使用了範型,所以要求jdk1.5以上。它的作者沒有像apache commons collections一樣照顧老的jdk版本,一個原因是google的jdk基本都是1.5以上,另一個原因是類型轉換實在是太難看了。現在的集合庫版本是1.0,已經很穩定了,在功能和實現方面也是廣泛參考意見(比如java.util之父Josh Bloch),所以該庫的質量可想而知,將來也有可能集成到jdk中。項目地址是http://code.google.com/p/google-collections/,該文對其提供的核心類做簡要的介紹。
Immutable Collections
在《effective java》的13條提到immutable class的好處及做法,有興趣的可以參考該節。在immutable collections方面,java.util.Collections類提供了一系列unmodifiableFoo的靜態方法供使用,這些unmodifiableFoo實際上是原有集合的視圖包裝,所以可以認爲新生成的不變集合和原有集合是同一對象,只是不變集合不能調用修改操作。這種效果有時並不是真正想要的,有時需要的是生成的不變集合和原有集合是分離的,原有集合的後續操作不影響不變集合。google collections就提供了該功能,具體的就包括ImmutableList、ImmutableMap、ImmutableSet等。下面給出一個示例片斷:
原有使用java.util.Collections的方法示例:
List<String> list = new ArrayList<String>();  list.add("1");  list.add("2");  list.add("3");  List<String> immutableList = Collections.unmodifiableList(list);
使用com.google.common.collect.ImmutableList示例:
List<String> immutableList = ImmutableList.of("1","2","3");
com.google.common.collect.ImmutableFoo都是通過調用靜態的of方法生成新的不變集合,該方法的參數是個可變數組。因爲ImmutableFoo只提供讀操作並自己維護數據,所以性能方面會比java.util中集合類有所提高。另外要說的是,不變集合並不能左右其包含的元素是否可變,所以不變集合中的元素最好也是不變的。
Multiset & Multimap
java.util.Set是個無序且元素不重複的集合。而Multiset是個無序但添加元素可重複的集合,對添加的重複元素,以計數表示多少。Multiset的實現也是支持多種類型的(比如Hash、LinkedList等)下面是使用片斷:
Multiset<String> set = HashMultiset.create();  set.add("kafka0102");  set.add("kafka0102");  ystem.out.println(set.count("kafka0102"));//輸出2  set.setCount("kafka0102", 5);  System.out.println(set.count("kafka0102"));//輸出5
這個Multiset還是有很多應用場景的,比如統計用戶訪問計數,沒有Multiset,就需要使用如Map來做,每次累加都需要先取出原有的計數值再加一後放回去,自然不如Multiset使用的方便。
Multimap也是很方便實用的集合,對於形如Multimap<K,V>的map,它相當於Map<K,Collection<V>>。如果實用Map來實現Multimap的功能,可想又是對Map的value進行三部曲操作。Multimap的實現也是支持多種類型的(比如Hash、LinkedList等)。使用Multimap的示例代碼如下:
 Multimap<String,String> map = HashMultimap.create();  map.put("kafka0102","1");  map.put("kafka0102","2");  ystem.out.println(map.get("kafka0102"));//輸出[2, 1]
BiMap
BiMap(bidirectional map)是個雙向的map。java.util.Map是個正向Map,也就是根據key查value,如果需要根據value查key,或者需要反向得到Map<V,K>,BiMap就是很好的選擇,否則就需要兩個Map來做。它的具體實現類有:EnumBiMap, EnumHashBiMap, HashBiMap, ImmutableBiMap。示例代碼如下:
 BiMap<String,String> map = HashBiMap.create();  map.put("kafka0102","1");  System.out.println(map.get("kafka0102"));  ystem.out.println(map.inverse().get("1");//輸出反向數據沒有提供單獨的函數,而是需要調用inverse().get
MapMaker
MapMaker是對ConcurrentMap的builder,它使得ConcurrentMap的key和value能是弱引用或軟引用類型。特別的,它提供的makeComputingMap方法能根據key計算出value來,當沒有對key來put value時,生成的ConcurrentMap能根據Function計算出value並和key關聯上,後續的訪問就不需要再次計算。代碼示例如下:
? ConcurrentMap<String, Integer> map = new MapMaker() .concurrencyLevel(32).softKeys().weakValues().expiration(30, TimeUnit.MINUTES).makeComputingMap( ? new Function<String, Integer>() { ? public Integer apply(String key) { ? return Integer.parseInt(key); ? } ? }); ? System.out.println(map.get("123"));//輸出123 ? map.put("123", 124); ? System.out.println(map.get("123"));//輸出124
google collections還提供一些實用的類,具體可參考它的API doc和http://publicobject.com/2007/09/series-recap-coding-in-small-with.html。該文雖行止於此,也很建議大家有時間研究下google collections的實現,這種基礎庫看起來簡單但要實現的優雅、高效是需要很見功夫的。

發佈了22 篇原創文章 · 獲贊 80 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章