<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 2.2-新集合類型 [原文鏈接](https://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained)?[譯文鏈接](http://ifeve.com/google-guava-newcollectiontypes)?**譯者:**沈義揚,校對:丁一 Guava引入了很多JDK沒有的、但我們發現明顯有用的新集合類型。這些新類型是為了和JDK集合框架共存,而沒有往JDK集合抽象中硬塞其他概念。作為一般規則,Guava集合非常精準地遵循了JDK接口契約。 ## Multiset 統計一個詞在文檔中出現了多少次,傳統的做法是這樣的: ``` Map<String, Integer> counts = new HashMap<String, Integer>(); for (String word : words) { Integer count = counts.get(word); if (count == null) { counts.put(word, 1); } else { counts.put(word, count + 1); } } ``` 這種寫法很笨拙,也容易出錯,并且不支持同時收集多種統計信息,如總詞數。我們可以做的更好。 Guava提供了一個新集合類型?[Multiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multiset.html),它可以多次添加相等的元素。維基百科從數學角度這樣定義Multiset:”集合[set]概念的延伸,它的元素可以重復出現…與集合[set]相同而與元組[tuple]相反的是,Multiset元素的順序是無關緊要的:Multiset {a, a, b}和{a, b, a}是相等的”。——_譯者注:這里所說的集合__[set]是數學上的概念,Multiset繼承自JDK中的Collection接口,而不是Set接口,所以包含重復元素并沒有違反原有的接口契約。_ 可以用兩種方式看待Multiset: * 沒有元素順序限制的ArrayList&lt;E&gt; * Map&lt;E, Integer&gt;,鍵為元素,值為計數 Guava的Multiset API也結合考慮了這兩種方式: 當把Multiset看成普通的Collection時,它表現得就像無序的ArrayList: * add(E)添加單個給定元素 * iterator()返回一個迭代器,包含Multiset的所有元素(包括重復的元素) * size()返回所有元素的總個數(包括重復的元素) 當把Multiset看作Map&lt;E, Integer&gt;時,它也提供了符合性能期望的查詢操作: * count(Object)返回給定元素的計數。HashMultiset.count的復雜度為O(1),TreeMultiset.count的復雜度為O(log n)。 * entrySet()返回Set&lt;Multiset.Entry&lt;E&gt;&gt;,和Map的entrySet類似。 * elementSet()返回所有不重復元素的Set&lt;E&gt;,和Map的keySet()類似。 * 所有Multiset實現的內存消耗隨著不重復元素的個數線性增長。 值得注意的是,除了極少數情況,Multiset和JDK中原有的Collection接口契約完全一致——具體來說,TreeMultiset在判斷元素是否相等時,與TreeSet一樣用compare,而不是Object.equals。另外特別注意,Multiset.addAll(Collection)可以添加Collection中的所有元素并進行計數,這比用for循環往Map添加元素和計數方便多了。 | **方法** | **描述** | |:--- |:--- | | [count(E)](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multiset.html#count%28java.lang.Object%29) | 給定元素在Multiset中的計數 | | [elementSet()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multiset.html#elementSet%28%29) | Multiset中不重復元素的集合,類型為Set&lt;E&gt; | | [entrySet()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multiset.html#entrySet%28%29) | 和Map的entrySet類似,返回Set&lt;Multiset.Entry&lt;E&gt;&gt;,其中包含的Entry支持getElement()和getCount()方法 | | [add(E, int)](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multiset.html#add%28java.lang.Object,int%29) | 增加給定元素在Multiset中的計數 | | [remove(E, int)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multiset.html#remove%28java.lang.Object, int%29) | 減少給定元素在Multiset中的計數 | | [setCount(E, int)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multiset.html#setCount%28E, int%29) | 設置給定元素在Multiset中的計數,不可以為負數 | | size() | 返回集合元素的總個數(包括重復的元素) | ### Multiset不是Map 請注意,Multiset&lt;E&gt;不是Map&lt;E, Integer&gt;,雖然Map可能是某些Multiset實現的一部分。準確來說Multiset是一種Collection類型,并履行了Collection接口相關的契約。關于Multiset和Map的顯著區別還包括: * Multiset中的元素計數只能是正數。任何元素的計數都不能為負,也不能是0。elementSet()和entrySet()視圖中也不會有這樣的元素。 * multiset.size()返回集合的大小,等同于所有元素計數的總和。對于不重復元素的個數,應使用elementSet().size()方法。(因此,add(E)把multiset.size()增加1) * multiset.iterator()會迭代重復元素,因此迭代長度等于multiset.size()。 * Multiset支持直接增加、減少或設置元素的計數。setCount(elem, 0)等同于移除所有elem。 * 對multiset?中沒有的元素,multiset.count(elem)始終返回0。 ### Multiset的各種實現 Guava提供了多種Multiset的實現,大致對應JDK中Map的各種實現: | **Map** | **對應的****Multiset** | **是否支持****null****元素** | |:--- |:--- |:--- | | HashMap | [HashMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/HashMultiset.html) | 是 | | TreeMap | [TreeMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/TreeMultiset.html) | 是(如果comparator支持的話) | | LinkedHashMap | [LinkedHashMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/LinkedHashMultiset.html) | 是 | | ConcurrentHashMap | [ConcurrentHashMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ConcurrentHashMultiset.html) | 否 | | ImmutableMap | [ImmutableMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMultiset.html) | 否 | ### SortedMultiset [SortedMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/SortedMultiset.html)是Multiset?接口的變種,它支持高效地獲取指定范圍的子集。比方說,你可以用?latencies.subMultiset(0,BoundType.CLOSED, 100, BoundType.OPEN).size()來統計你的站點中延遲在100毫秒以內的訪問,然后把這個值和latencies.size()相比,以獲取這個延遲水平在總體訪問中的比例。 TreeMultiset實現SortedMultiset接口。在撰寫本文檔時,ImmutableSortedMultiset還在測試和GWT的兼容性。 ## Multimap 每個有經驗的Java程序員都在某處實現過Map&lt;K, List&lt;V&gt;&gt;或Map&lt;K, Set&lt;V&gt;&gt;,并且要忍受這個結構的笨拙。例如,Map&lt;K, Set&lt;V&gt;&gt;通常用來表示非標定有向圖。Guava的?[Multimap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html)可以很容易地把一個鍵映射到多個值。換句話說,Multimap是把鍵映射到任意多個值的一般方式。 可以用兩種方式思考Multimap的概念:”鍵-單個值映射”的集合: ``` a -> 1 a -> 2 a ->4 b -> 3 c -> 5 ``` 或者”鍵-值集合映射”的映射: ``` a -> [1, 2, 4] b -> 3 c -> 5 ``` 一般來說,Multimap接口應該用第一種方式看待,但asMap()視圖返回Map&lt;K, Collection&lt;V&gt;&gt;,讓你可以按另一種方式看待Multimap。重要的是,不會有任何鍵映射到空集合:一個鍵要么至少到一個值,要么根本就不在Multimap中。 很少會直接使用Multimap接口,更多時候你會用ListMultimap或SetMultimap接口,它們分別把鍵映射到List或Set。 ### 修改Multimap [Multimap.get(key)](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html#get%28K%29)以集合形式返回鍵所對應的值視圖,即使沒有任何對應的值,也會返回空集合。ListMultimap.get(key)返回List,SetMultimap.get(key)返回Set。 對值視圖集合進行的修改最終都會反映到底層的Multimap。例如: ``` Set<Person> aliceChildren = childrenMultimap.get(alice); aliceChildren.clear(); aliceChildren.add(bob); aliceChildren.add(carol); ``` 其他(更直接地)修改Multimap的方法有: | **方法簽名** | **描述** | **等價于** | |:--- |:--- |:--- | | [put(K, V)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimap.html#put%28K, V%29) | 添加鍵到單個值的映射 | multimap.get(key).add(value) | | [putAll(K, Iterable&lt;V&gt;)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimap.html#putAll%28K, java.lang.Iterable%29) | 依次添加鍵到多個值的映射 | Iterables.addAll(multimap.get(key), values) | | [remove(K, V)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimap.html#remove%28java.lang.Object, java.lang.Object%29) | 移除鍵到值的映射;如果有這樣的鍵值并成功移除,返回true。 | multimap.get(key).remove(value) | | [removeAll(K)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimap.html#removeAll%28java.lang.Object%29) | 清除鍵對應的所有值,返回的集合包含所有之前映射到K的值,但修改這個集合就不會影響Multimap了。 | multimap.get(key).clear() | | [replaceValues(K, Iterable&lt;V&gt;)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimap.html#replaceValues%28K, java.lang.Iterable%29) | 清除鍵對應的所有值,并重新把key關聯到Iterable中的每個元素。返回的集合包含所有之前映射到K的值。 | multimap.get(key).clear(); Iterables.addAll(multimap.get(key), values) | ### Multimap的視圖 Multimap還支持若干強大的視圖: * [`asMap`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html#asMap%28%29)為Multimap&lt;K, V&gt;提供Map&lt;K,Collection&lt;V&gt;&gt;形式的視圖。返回的Map支持remove操作,并且會反映到底層的Multimap,但它不支持put或putAll操作。更重要的是,如果你想為Multimap中沒有的鍵返回null,而不是一個新的、可寫的空集合,你就可以使用asMap().get(key)。(你可以并且應當把asMap.get(key)返回的結果轉化為適當的集合類型——如SetMultimap.asMap.get(key)的結果轉為Set,ListMultimap.asMap.get(key)的結果轉為List——Java類型系統不允許ListMultimap直接為asMap.get(key)返回List——_譯者注:也可以用__Multimaps中的asMap靜態方法幫你完成類型轉換_) * [`entries`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html#entries%28%29)用Collection&lt;Map.Entry&lt;K, V&gt;&gt;返回Multimap中所有”鍵-單個值映射”——包括重復鍵。(對SetMultimap,返回的是Set) * [`keySet`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html#keySet%28%29)用Set表示Multimap中所有不同的鍵。 * [`keys`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html#keys%28%29)用Multiset表示Multimap中的所有鍵,每個鍵重復出現的次數等于它映射的值的個數。可以從這個Multiset中移除元素,但不能做添加操作;移除操作會反映到底層的Multimap。 * [`values()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimap.html#values%28%29)用一個”扁平”的Collection&lt;V&gt;包含Multimap中的所有值。這有一點類似于Iterables.concat(multimap.asMap().values()),但它直接返回了單個Collection,而不像multimap.asMap().values()那樣是按鍵區分開的Collection。 ### Multimap不是Map Multimap&lt;K, V&gt;不是Map&lt;K,Collection&lt;V&gt;&gt;,雖然某些Multimap實現中可能使用了map。它們之間的顯著區別包括: * Multimap.get(key)總是返回非null、但是可能空的集合。這并不意味著Multimap為相應的鍵花費內存創建了集合,而只是提供一個集合視圖方便你為鍵增加映射值——_譯者注:如果有這樣的鍵,返回的集合只是包裝了__Multimap中已有的集合;如果沒有這樣的鍵,返回的空集合也只是持有Multimap引用的棧對象,讓你可以用來操作底層的Multimap。因此,返回的集合不會占據太多內存,數據實際上還是存放在Multimap中。_ * 如果你更喜歡像Map那樣,為Multimap中沒有的鍵返回null,請使用asMap()視圖獲取一個Map&lt;K, Collection&lt;V&gt;&gt;。(或者用靜態方法[Multimaps.asMap()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimaps.html#asMap%28com.google.common.collect.ListMultimap%29)為ListMultimap返回一個Map&lt;K, List&lt;V&gt;&gt;。對于SetMultimap和SortedSetMultimap,也有類似的靜態方法存在) * 當且僅當有值映射到鍵時,Multimap.containsKey(key)才會返回true。尤其需要注意的是,如果鍵k之前映射過一個或多個值,但它們都被移除后,Multimap.containsKey(key)會返回false。 * Multimap.entries()返回Multimap中所有”鍵-單個值映射”——包括重復鍵。如果你想要得到所有”鍵-值集合映射”,請使用asMap().entrySet()。 * Multimap.size()返回所有”鍵-單個值映射”的個數,而非不同鍵的個數。要得到不同鍵的個數,請改用Multimap.keySet().size()。 ### Multimap的各種實現 Multimap提供了多種形式的實現。在大多數要使用Map&lt;K, Collection&lt;V&gt;&gt;的地方,你都可以使用它們: | **實現** | **鍵行為類似** | **值行為類似** | |:--- |:--- |:--- | | [ArrayListMultimap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ArrayListMultimap.html) | HashMap | ArrayList | | [HashMultimap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/HashMultimap.html) | HashMap | HashSet | | [LinkedListMultimap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/LinkedListMultimap.html)* | LinkedHashMap* | LinkedList* | | [LinkedHashMultimap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/LinkedHashMultimap.html)** | LinkedHashMap | LinkedHashMap | | [TreeMultimap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/TreeMultimap.html) | TreeMap | TreeSet | | [`ImmutableListMultimap`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableListMultimap.html) | ImmutableMap | ImmutableList | | [ImmutableSetMultimap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableSetMultimap.html) | ImmutableMap | ImmutableSet | 除了兩個不可變形式的實現,其他所有實現都支持null鍵和null值 *LinkedListMultimap.entries()保留了所有鍵和值的迭代順序。詳情見doc鏈接。 **LinkedHashMultimap保留了映射項的插入順序,包括鍵插入的順序,以及鍵映射的所有值的插入順序。 請注意,并非所有的Multimap都和上面列出的一樣,使用Map&lt;K, Collection&lt;V&gt;&gt;來實現(特別是,一些Multimap實現用了自定義的hashTable,以最小化開銷) 如果你想要更大的定制化,請用[Multimaps.newMultimap(Map, Supplier&lt;Collection&gt;)](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/co…ultimaps.html#newMultimap%28java.util.Map,%20com.google.common.base.Supplier%29)或[list](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimaps.html#newListMultimap%28java.util.Map, com.google.common.base.Supplier%29)和?[set](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimaps.html#newSetMultimap%28java.util.Map, com.google.common.base.Supplier%29)版本,使用自定義的Collection、List或Set實現Multimap。 ## BiMap 傳統上,實現鍵值對的雙向映射需要維護兩個單獨的map,并保持它們間的同步。但這種方式很容易出錯,而且對于值已經在map中的情況,會變得非常混亂。例如: ``` Map<String, Integer> nameToId = Maps.newHashMap(); Map<Integer, String> idToName = Maps.newHashMap(); nameToId.put("Bob", 42); idToName.put(42, "Bob"); //如果"Bob"和42已經在map中了,會發生什么? //如果我們忘了同步兩個map,會有詭異的bug發生... ``` [BiMap&lt;K, V&gt;](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/BiMap.html)是特殊的Map: * 可以用?[inverse()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/BiMap.html#inverse%28%29)反轉BiMap&lt;K, V&gt;的鍵值映射 * 保證值是唯一的,因此?[values()](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/BiMap.html#values%28%29)返回Set而不是普通的Collection 在BiMap中,如果你想把鍵映射到已經存在的值,會拋出IllegalArgumentException異常。如果對特定值,你想要強制替換它的鍵,請使用?[BiMap.forcePut(key, value)](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/BiMap.html#forcePut%28java.lang.Object,java.lang.Object%29)。 ``` BiMap<String, Integer> userId = HashBiMap.create(); ... String userForId = userId.inverse().get(id); ``` ### BiMap的各種實現 | **鍵****–****值實現** | **值****–****鍵實現** | **對應的****BiMap****實現** | |:--- |:--- |:--- | | HashMap | HashMap | [HashBiMap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/HashBiMap.html) | | ImmutableMap | ImmutableMap | [ImmutableBiMap](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableBiMap.html) | | EnumMap | EnumMap | [EnumBiMap](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/EnumBiMap.html) | | EnumMap | HashMap | [EnumHashBiMap](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/EnumHashBiMap.html) | 注:[Maps](https://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Maps)類中還有一些諸如synchronizedBiMap的BiMap工具方法. ## Table ``` Table<Vertex, Vertex, Double> weightedGraph = HashBasedTable.create(); weightedGraph.put(v1, v2, 4); weightedGraph.put(v1, v3, 20); weightedGraph.put(v2, v3, 5); weightedGraph.row(v1); // returns a Map mapping v2 to 4, v3 to 20 weightedGraph.column(v3); // returns a Map mapping v1 to 20, v2 to 5 ``` 通常來說,當你想使用多個鍵做索引的時候,你可能會用類似Map&lt;FirstName, Map&lt;LastName, Person&gt;&gt;的實現,這種方式很丑陋,使用上也不友好。Guava為此提供了新集合類型[Table](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html),它有兩個支持所有類型的鍵:”行”和”列”。Table提供多種視圖,以便你從各種角度使用它: * [rowMap()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html#rowMap%28%29):用Map&lt;R, Map&lt;C, V&gt;&gt;表現Table&lt;R, C, V&gt;。同樣的,?[rowKeySet()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html#rowKeySet%28%29)返回”行”的集合Set&lt;R&gt;。 * [row(r)](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html#row%28R%29) :用Map&lt;C, V&gt;返回給定”行”的所有列,對這個map進行的寫操作也將寫入Table中。 * 類似的列訪問方法:[columnMap()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html#columnMap%28%29)、[columnKeySet()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html#columnKeySet%28%29)、[column(c)](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html#column%28C%29)。(基于列的訪問會比基于的行訪問稍微低效點) * [cellSet()](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html#cellSet%28%29):用元素類型為[Table.Cell&lt;R, C, V&gt;](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.Cell.html)的Set表現Table&lt;R, C, V&gt;。Cell類似于Map.Entry,但它是用行和列兩個鍵區分的。 Table有如下幾種實現: * [HashBasedTable](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/HashBasedTable.html):本質上用HashMap&lt;R, HashMap&lt;C, V&gt;&gt;實現; * [TreeBasedTable](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/TreeBasedTable.html):本質上用TreeMap&lt;R, TreeMap&lt;C,V&gt;&gt;實現; * [ImmutableTable](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/ImmutableTable.html):本質上用ImmutableMap&lt;R, ImmutableMap&lt;C, V&gt;&gt;實現;注:ImmutableTable對稀疏或密集的數據集都有優化。 * [ArrayTable](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ArrayTable.html):要求在構造時就指定行和列的大小,本質上由一個二維數組實現,以提升訪問速度和密集Table的內存利用率。ArrayTable與其他Table的工作原理有點不同,請參見Javadoc了解詳情。 ## ClassToInstanceMap [ClassToInstanceMap](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/ClassToInstanceMap.html)是一種特殊的Map:它的鍵是類型,而值是符合鍵所指類型的對象。 為了擴展Map接口,ClassToInstanceMap額外聲明了兩個方法:[T getInstance(Class&lt;T&gt;)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/ClassToInstanceMap.html#getInstance%28java.lang.Class%29)?和[T putInstance(Class&lt;T&gt;, T)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…llect/ClassToInstanceMap.html#putInstance%28java.lang.Class,java.lang.Object%29),從而避免強制類型轉換,同時保證了類型安全。 ClassToInstanceMap有唯一的泛型參數,通常稱為B,代表Map支持的所有類型的上界。例如: ``` ClassToInstanceMap<Number> numberDefaults=MutableClassToInstanceMap.create(); numberDefaults.putInstance(Integer.class, Integer.valueOf(0)); ``` 從技術上講,ClassToInstanceMap&lt;B&gt;實現了Map&lt;Class&lt;? extends B&gt;, B&gt;——或者換句話說,是一個映射B的子類型到對應實例的Map。這讓ClassToInstanceMap包含的泛型聲明有點令人困惑,但請記住B始終是Map所支持類型的上界——通常B就是Object。 對于ClassToInstanceMap,Guava提供了兩種有用的實現:[MutableClassToInstanceMap](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/MutableClassToInstanceMap.html)和?[ImmutableClassToInstanceMap](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/ImmutableClassToInstanceMap.html)。 ## RangeSet RangeSet描述了一組不相連的、非空的區間。當把一個區間添加到可變的RangeSet時,所有相連的區間會被合并,空區間會被忽略。例如: ``` RangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); // {[1,10]} rangeSet.add(Range.closedOpen(11, 15));//不相連區間:{[1,10], [11,15)} rangeSet.add(Range.closedOpen(15, 20)); //相連區間; {[1,10], [11,20)} rangeSet.add(Range.openClosed(0, 0)); //空區間; {[1,10], [11,20)} rangeSet.remove(Range.open(5, 10)); //分割[1, 10]; {[1,5], [10,10], [11,20)} ``` 請注意,要合并Range.closed(1, 10)和Range.closedOpen(11, 15)這樣的區間,你需要首先用[Range.canonical(DiscreteDomain)](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…mmon/collect/Range.html#canonical%28com.google.common.collect.DiscreteDomain%29)對區間進行預處理,例如DiscreteDomain.integers()。 注:RangeSet不支持GWT,也不支持JDK5和更早版本;因為,RangeSet需要充分利用JDK6中NavigableMap的特性。 ### RangeSet的視圖 RangeSet的實現支持非常廣泛的視圖: * complement():返回RangeSet的補集視圖。complement也是RangeSet類型,包含了不相連的、非空的區間。 * subRangeSet(Range&lt;C&gt;):返回RangeSet與給定Range的交集視圖。這擴展了傳統排序集合中的headSet、subSet和tailSet操作。 * asRanges():用Set&lt;Range&lt;C&gt;&gt;表現RangeSet,這樣可以遍歷其中的Range。 * asSet(DiscreteDomain&lt;C&gt;)(僅ImmutableRangeSet支持):用ImmutableSortedSet&lt;C&gt;表現RangeSet,以區間中所有元素的形式而不是區間本身的形式查看。(這個操作不支持DiscreteDomain?和RangeSet都沒有上邊界,或都沒有下邊界的情況) ### RangeSet的查詢方法 為了方便操作,RangeSet直接提供了若干查詢方法,其中最突出的有: * contains(C):RangeSet最基本的操作,判斷RangeSet中是否有任何區間包含給定元素。 * rangeContaining(C):返回包含給定元素的區間;若沒有這樣的區間,則返回null。 * encloses(Range&lt;C&gt;):簡單明了,判斷RangeSet中是否有任何區間包括給定區間。 * span():返回包括RangeSet中所有區間的最小區間。 ## RangeMap RangeMap描述了”不相交的、非空的區間”到特定值的映射。和RangeSet不同,RangeMap不會合并相鄰的映射,即便相鄰的區間映射到相同的值。例如: ``` RangeMap<Integer, String> rangeMap = TreeRangeMap.create(); rangeMap.put(Range.closed(1, 10), "foo"); //{[1,10] => "foo"} rangeMap.put(Range.open(3, 6), "bar"); //{[1,3] => "foo", (3,6) => "bar", [6,10] => "foo"} rangeMap.put(Range.open(10, 20), "foo"); //{[1,3] => "foo", (3,6) => "bar", [6,10] => "foo", (10,20) => "foo"} rangeMap.remove(Range.closed(5, 11)); //{[1,3] => "foo", (3,5) => "bar", (11,20) => "foo"} ``` ### RangeMap的視圖 RangeMap提供兩個視圖: * asMapOfRanges():用Map&lt;Range&lt;K&gt;, V&gt;表現RangeMap。這可以用來遍歷RangeMap。 * subRangeMap(Range&lt;K&gt;):用RangeMap類型返回RangeMap與給定Range的交集視圖。這擴展了傳統的headMap、subMap和tailMap操作。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看