免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Google Guava Collections 使用介紹

Google Guava Collections 使用介紹

Google Guava Collections(以下都簡(jiǎn)稱為 Guava Collections)是 Java Collections Framework 的增強(qiáng)和擴(kuò)展。每個(gè) Java 開發(fā)者都會(huì)在工作中使用各種數(shù)據(jù)結(jié)構(gòu),很多情況下 Java Collections Framework 可以幫助你完成這類工作。但是在有些場(chǎng)合你使用了 Java Collections Framework 的 API,但還是需要寫很多代碼來實(shí)現(xiàn)一些復(fù)雜邏輯,這個(gè)時(shí)候就可以嘗試使用 Guava Collections 來幫助你完成這些工作。這些高質(zhì)量的 API 使你的代碼更短,更易于閱讀和修改,工作更加輕松。

目標(biāo)讀者

對(duì)于理解 Java 開源工具來說,本文讀者至少應(yīng)具備基礎(chǔ)的 Java 知識(shí),特別是 JDK5 的特性。因?yàn)?Guava Collections 充分使用了范型,循環(huán)增強(qiáng)這樣的特性。作為 Java Collections Framework 的增強(qiáng),讀者必須對(duì) Java Collections Framework 有清晰的理解,包括主要的接口約定和常用的實(shí)現(xiàn)類。并且 Guava Collections 很大程度上是幫助開發(fā)者完成比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu)的操作,因此基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)和算法的知識(shí)也是清晰理解 Guava Collections 的必要條件。

項(xiàng)目背景

Guava Collections 是 Google 的工程師 Kevin Bourrillion 和 Jared Levy 在著名"20%"時(shí)間寫的代碼。當(dāng)然作為開源項(xiàng)目還有其他的開發(fā)者貢獻(xiàn)了代碼。在編寫的過程中,Java Collections Framework 的作者 Joshua Bloch 也參與了代碼審核和提出建議。目前它已經(jīng)移到另外一個(gè)叫 guava-libraries 的開源項(xiàng)目下面來維護(hù)。

因?yàn)楣δ芟嗨贫矣滞情_源項(xiàng)目,人們很很自然會(huì)把它和 Apache Commons Collections 來做比較。其區(qū)別歸結(jié)起來有以下幾點(diǎn):

Guava Collections 充分利用了 JDK5 的范型和枚舉這樣的特性,而 Apache Commons Collections 則是基于 JDK1.2。其次 Guava Collections 更加嚴(yán)格遵守 Java Collections Framework 定義的接口契約,而在 Apache Commons Collections 你會(huì)發(fā)現(xiàn)不少違反這些 JDK 接口契約的地方。這些不遵守標(biāo)準(zhǔn)的地方就是出 bug 的風(fēng)險(xiǎn)很高。最后 Guava Collections 處于積極的維護(hù)狀態(tài),本文介紹的特性都基于目前最新 2011 年 4 月的 Guava r09 版本,而 Apache Commons Collections 最新一次發(fā)布也已經(jīng)是 2008 年了。

功能列舉

可以說 Java Collections Framework 滿足了我們大多數(shù)情況下使用集合的要求,但是當(dāng)遇到一些特殊的情況我們的代碼會(huì)比較冗長(zhǎng),比較容易出錯(cuò)。Guava Collections 可以幫助你的代碼更簡(jiǎn)短精煉,更重要是它增強(qiáng)了代碼的可讀性。看看 Guava Collections 為我們做了哪些很酷的事情。

  • Immutable Collections: 還在使用 Collections.unmodifiableXXX() ? Immutable Collections 這才是真正的不可修改的集合
  • Multiset: 看看如何把重復(fù)的元素放入一個(gè)集合
  • Multimaps: 需要在一個(gè) key 對(duì)應(yīng)多個(gè) value 的時(shí)候 , 自己寫一個(gè)實(shí)現(xiàn)比較繁瑣 - 讓 Multimaps 來幫忙
  • BiMap: java.util.Map 只能保證 key 的不重復(fù),BiMap 保證 value 也不重復(fù)
  • MapMaker: 超級(jí)強(qiáng)大的 Map 構(gòu)造類
  • Ordering class: 大家知道用 Comparator 作為比較器來對(duì)集合排序,但是對(duì)于多關(guān)鍵字排序 Ordering class 可以簡(jiǎn)化很多的代碼
  • 其他特性

當(dāng)然,如果沒有 Guava Collections 你也可以用 Java Collections Framework 完成上面的功能。但是 Guava Collections 提供的這些 API 經(jīng)過精心設(shè)計(jì),而且還有 25000 個(gè)單元測(cè)試來保障它的質(zhì)量。所以我們沒必要重新發(fā)明輪子。接下來我們來詳細(xì)看看 Guava Collections 的一些具體功能。

Immutable Collections: 真正的不可修改的集合

大家都用過 Collections.unmodifiableXXX() 來做一個(gè)不可修改的集合。例如你要構(gòu)造存儲(chǔ)常量的 Set,你可以這樣來做 :

 Set<String> set = new HashSet<String>(Arrays.asList(new String[]{"RED", "GREEN"}));  Set<String> unmodifiableSet = Collections.unmodifiableSet(set);

這看上去似乎不錯(cuò),因?yàn)槊看握{(diào) unmodifiableSet.add() 都會(huì)拋出一個(gè) UnsupportedOperationException。感覺安全了?慢!如果有人在原來的 set 上 add 或者 remove 元素會(huì)怎么樣?結(jié)果 unmodifiableSet 也是被 add 或者 remove 元素了。而且構(gòu)造這樣一個(gè)簡(jiǎn)單的 set 寫了兩句長(zhǎng)的代碼。下面看看 ImmutableSet 是怎么來做地更安全和簡(jiǎn)潔 :

 ImmutableSet<String> immutableSet = ImmutableSet.of("RED", "GREEN");

就這樣一句就夠了,而且試圖調(diào) add 方法的時(shí)候,它一樣會(huì)拋出 UnsupportedOperationException。重要的是代碼的可讀性增強(qiáng)了不少,非常直觀地展現(xiàn)了代碼的用意。如果像之前這個(gè)代碼保護(hù)一個(gè) set 怎么做呢?你可以 :

 ImmutableSet<String> immutableSet = ImmutableSet.copyOf(set);

從構(gòu)造的方式來說,ImmutableSet 集合還提供了 Builder 模式來構(gòu)造一個(gè)集合 :

 Builder<String>  builder = ImmutableSet.builder();  ImmutableSet<String> immutableSet = builder.add("RED").addAll(set).build();

在這個(gè)例子里面 Builder 不但能加入單個(gè)元素還能加入既有的集合。

除此之外,Guava Collections 還提供了各種 Immutable 集合的實(shí)現(xiàn):ImmutableList,ImmutableMap,ImmutableSortedSet,ImmutableSortedMap。

Multiset: 把重復(fù)的元素放入集合

你可能會(huì)說這和 Set 接口的契約沖突,因?yàn)?Set 接口的 JavaDoc 里面規(guī)定不能放入重復(fù)元素。事實(shí)上,Multiset 并沒有實(shí)現(xiàn) java.util.Set 接口,它更像是一個(gè) Bag。普通的 Set 就像這樣 :[car, ship, bike],而 Multiset 會(huì)是這樣 : [car x 2, ship x 6, bike x 3]。

譬如一個(gè) List 里面有各種字符串,然后你要統(tǒng)計(jì)每個(gè)字符串在 List 里面出現(xiàn)的次數(shù) :

 Map<String, Integer> map = new HashMap<String, Integer>();  for(String word : wordList){     Integer count = map.get(word);     map.put(word, (count == null) ? 1 : count + 1);  }  //count word “the” Integer count = map.get(“the”);

如果用 Multiset 就可以這樣 :

 HashMultiset<String> multiSet = HashMultiset.create();  multiSet.addAll(wordList);  //count word “the” Integer count = multiSet.count(“the”);

這樣連循環(huán)都不用了,而且 Multiset 用的方法叫 count,顯然比在 Map 里面調(diào) get 有更好的可讀性。Multiset 還提供了 setCount 這樣設(shè)定元素重復(fù)次數(shù)的方法,雖然你可以通過使用 Map 來實(shí)現(xiàn)類似的功能,但是程序的可讀性比 Multiset 差了很多。

常用實(shí)現(xiàn) Multiset 接口的類有:

  • HashMultiset: 元素存放于 HashMap
  • LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素的排列順序由第一次放入的順序決定
  • TreeMultiset:元素被排序存放于TreeMap
  • EnumMultiset: 元素必須是 enum 類型
  • ImmutableMultiset: 不可修改的 Mutiset

看到這里你可能已經(jīng)發(fā)現(xiàn) Guava Collections 都是以 create 或是 of 這樣的靜態(tài)方法來構(gòu)造對(duì)象。這是因?yàn)檫@些集合類大多有多個(gè)參數(shù)的私有構(gòu)造方法,由于參數(shù)數(shù)目很多,客戶代碼程序員使用起來就很不方便。而且以這種方式可以返回原類型的子類型對(duì)象。另外,對(duì)于創(chuàng)建范型對(duì)象來講,這種方式更加簡(jiǎn)潔。

Multimap: 在 Map 的 value 里面放多個(gè)元素

Muitimap 就是一個(gè) key 對(duì)應(yīng)多個(gè) value 的數(shù)據(jù)結(jié)構(gòu)??瓷先ニ芟?java.util.Map 的結(jié)構(gòu),但是 Muitimap 不是 Map,沒有實(shí)現(xiàn) Map 的接口。設(shè)想你對(duì) Map 調(diào)了 2 次參數(shù) key 一樣的 put 方法,結(jié)果就是第 2 次的 value 覆蓋了第 1 次的 value。但是對(duì) Muitimap 來說這個(gè) key 同時(shí)對(duì)應(yīng)了 2 個(gè) value。所以 Map 看上去是 : {k1=v1, k2=v2,...},而 Muitimap 是 :{k1=[v1, v2, v3], k2=[v7, v8],....}。

舉個(gè)記名投票的例子。所有選票都放在一個(gè) List<Ticket> 里面,List 的每個(gè)元素包括投票人和選舉人的名字。我們可以這樣寫 :

 //Key is candidate name, its value is his voters  HashMap<String, HashSet<String>> hMap = new HashMap<String, HashSet<String>>();  for(Ticket ticket: tickets){     HashSet<String> set = hMap.get(ticket.getCandidate());     if(set == null){         set = new HashSet<String>();         hMap.put(ticket.getCandidate(), set);     }     set.add(ticket.getVoter());  }

我們?cè)賮砜纯?Muitimap 能做些什么 :

 HashMultimap<String, String> map = HashMultimap.create();  for(Ticket ticket: tickets){     map.put(ticket.getCandidate(), ticket.getVoter());  }

就這么簡(jiǎn)單!

Muitimap 接口的主要實(shí)現(xiàn)類有:

  • HashMultimap: key 放在 HashMap,而 value 放在 HashSet,即一個(gè) key 對(duì)應(yīng)的 value 不可重復(fù)
  • ArrayListMultimap: key 放在 HashMap,而 value 放在 ArrayList,即一個(gè) key 對(duì)應(yīng)的 value 有順序可重復(fù)
  • LinkedHashMultimap: key 放在 LinkedHashMap,而 value 放在 LinkedHashSet,即一個(gè) key 對(duì)應(yīng)的 value 有順序不可重復(fù)
  • TreeMultimap: key 放在 TreeMap,而 value 放在 TreeSet,即一個(gè) key 對(duì)應(yīng)的 value 有排列順序
  • ImmutableMultimap: 不可修改的 Multimap

BiMap: 雙向 Map

BiMap 實(shí)現(xiàn)了 java.util.Map 接口。它的特點(diǎn)是它的 value 和它 key 一樣也是不可重復(fù)的,換句話說它的 key 和 value 是等價(jià)的。如果你往 BiMap 的 value 里面放了重復(fù)的元素,就會(huì)得到 IllegalArgumentException。

舉個(gè)例子,你可能經(jīng)常會(huì)碰到在 Map 里面根據(jù) value 值來反推它的 key 值的邏輯:

 for(Map.Entry<User, Address> entry : map.entreSet()){     if(entry.getValue().equals(anAddess)){         return entry.getKey();     }  }  return null;

如果把 User 和 Address 都放在 BiMap,那么一句代碼就得到結(jié)果了:

 return biMap.inverse().get(anAddess);

這里的 inverse 方法就是把 BiMap 的 key 集合 value 集合對(duì)調(diào),因此 biMap == biMap.inverse().inverse()。

BiMap的常用實(shí)現(xiàn)有:

HashBiMap: key 集合與 value 集合都有 HashMap 實(shí)現(xiàn)

EnumBiMap: key 與 value 都必須是 enum 類型

ImmutableBiMap: 不可修改的 BiMap

MapMaker: 超級(jí)強(qiáng)大的 Map 構(gòu)造工具

MapMaker 是用來構(gòu)造 ConcurrentMap 的工具類。為什么可以把 MapMaker 叫做超級(jí)強(qiáng)大?看了下面的例子你就知道了。首先,它可以用來構(gòu)造 ConcurrentHashMap:

 //ConcurrentHashMap with concurrency level 8  ConcurrentMap<String, Object> map1 = new MapMaker()     .concurrencyLevel(8)      .makeMap();

或者構(gòu)造用各種不同 reference 作為 key 和 value 的 Map:

 //ConcurrentMap with soft reference key and weak reference value  ConcurrentMap<String, Object> map2 = new MapMaker()     .softKeys()     .weakValues()     .makeMap();

或者構(gòu)造有自動(dòng)移除時(shí)間過期項(xiàng)的 Map:

 //Automatically removed entries from map after 30 seconds since they are created  ConcurrentMap<String, Object> map3 = new MapMaker()     .expireAfterWrite(30, TimeUnit.SECONDS)     .makeMap();

或者構(gòu)造有最大限制數(shù)目的 Map:

 //Map size grows close to the 100, the map will evict  //entries that are less likely to be used again  ConcurrentMap<String, Object> map4 = new MapMaker()     .maximumSize(100)     .makeMap();

或者提供當(dāng) Map 里面不包含所 get 的項(xiàng),而需要自動(dòng)加入到 Map 的功能。這個(gè)功能當(dāng) Map 作為緩存的時(shí)候很有用 :

 //Create an Object to the map, when get() is missing in map  ConcurrentMap<String, Object> map5 = new MapMaker()     .makeComputingMap(       new Function<String, Object>() {         public Object apply(String key) {           return createObject(key);     }});

這些還不是最強(qiáng)大的特性,最厲害的是 MapMaker 可以提供擁有以上所有特性的 Map:

 //Put all features together!  ConcurrentMap<String, Object> mapAll = new MapMaker()     .concurrencyLevel(8)     .softKeys()     .weakValues()     .expireAfterWrite(30, TimeUnit.SECONDS)     .maximumSize(100)     .makeComputingMap(       new Function<String, Object>() {         public Object apply(String key) {           return createObject(key);      }});

Ordering class: 靈活的多字段排序比較器

要對(duì)集合排序或者求最大值最小值,首推 java.util.Collections 類,但關(guān)鍵是要提供 Comparator 接口的實(shí)現(xiàn)。假設(shè)有個(gè)待排序的 List<Foo>,而 Foo 里面有兩個(gè)排序關(guān)鍵字 int a, int b 和 int c:

 Collections.sort(list, new Comparator<Foo>(){        @Override        public int compare(Foo f1, Foo f2) {            int resultA = f1.a – f2.a;         int resultB = f1.b – f2.b;         return  resultA == 0 ? (resultB == 0 ? f1.c – f2.c : resultB) : resultA;

}});

這看上去有點(diǎn)眼暈,如果用一串 if-else 也好不到哪里去??纯?ComparisonChain 能做到什么 :

 Collections.sort(list, new Comparator<Foo>(){        @Override     return ComparisonChain.start()           .compare(f1.a, f2.a)           .compare(f1.b, f2.b)          .compare(f1.c, f2.c).result();          }});

如果排序關(guān)鍵字要用自定義比較器,compare 方法也有接受 Comparator 的重載版本。譬如 Foo 里面每個(gè)排序關(guān)鍵字都已經(jīng)有了各自的 Comparator,那么利用 ComparisonChain 可以 :

 Collections.sort(list, new Comparator<Foo>(){        @Override     return ComparisonChain.start()           .compare(f1.a, f2.a, comparatorA)           .compare(f1.b, f2.b, comparatorB)          .compare(f1.c, f2.c, comparatorC).result();          }});

Ordring 類還提供了一個(gè)組合 Comparator 對(duì)象的方法。而且 Ordring 本身實(shí)現(xiàn)了 Comparator 接口所以它能直接作為 Comparator 使用:

 Ordering<Foo> ordering = Ordering.compound(     Arrays.asList(comparatorA, comparatorB, comparatorc));  Collections.sort(list, ordering);

其他特性 :

過濾器:利用 Collections2.filter() 方法過濾集合中不符合條件的元素。譬如過濾一個(gè) List<Integer> 里面小于 10 的元素 :

 Collection<Integer>  filterCollection =         Collections2.filter(list, new Predicate<Integer>(){     @Override     public boolean apply(Integer input) {         return input >= 10;  }});

當(dāng)然,你可以自己寫一個(gè)循環(huán)來實(shí)現(xiàn)這個(gè)功能,但是這樣不能保證之后小于 10 的元素不被放入集合。filter 的強(qiáng)大之處在于返回的 filterCollection 仍然有排斥小于 10 的元素的特性,如果調(diào) filterCollection.add(9) 就會(huì)得到一個(gè) IllegalArgumentException。

轉(zhuǎn)換器:利用 Collections2.transform() 方法來轉(zhuǎn)換集合中的元素。譬如把一個(gè) Set<Integer> 里面所有元素都轉(zhuǎn)換成帶格式的 String 來產(chǎn)生新的 Collection<String>:

 Collection<String>  formatCollection =       Collections2.transform(set, new Function<Integer, String>(){     @Override     public String apply(Integer input) {         return new DecimalFormat("#,###").format(input);  }} );

下載與使用

這個(gè)開源項(xiàng)目發(fā)布的 jar 包可以在它的官方網(wǎng)站內(nèi)(http://code.google.com/p/guava-libraries/downloads/list)找到。其下載的 zip 包中含有 Guava Collections 的 jar 包 guava-r09.jar 及其依賴包 guava-r09-gwt.jar,javadoc,源代碼,readme 等文件。使用時(shí)只需將 guava-r09.jar 和依賴包 guava-r09-gwt.jar 放入 CLASSPATH 中即可。

如果您使用 Maven 作為構(gòu)建工具的話可以在 pom.xml 內(nèi)加入:

 <dependency>     <groupId>com.google.guava</groupId>     <artifactId>guava</artifactId>     <version>r09</version>  </dependency>

需要注意的是本文介紹的 Guava r09 需要 1.5 或者更高版本的 JDK。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Google Guava的介紹和使用(轉(zhuǎn))
Guava介紹 – Google的Java常用類庫 | 和大頭的博客
為什么強(qiáng)烈推薦Java程序員使用Google Guava編程
google collection
Guava學(xué)習(xí)筆記:Immutable(不可變)集合
走近Guava(三): 集合
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服