天天看點

[Google Guava] 2.3-強大的集合工具類:java.util.Collections中未包含的集合工具

尚未完成: queues, tables工具類

我們用相對直覺的方式把工具類與特定集合接口的對應關系歸納如下:

<b>集合接口</b><b></b>

<b>屬于</b><b>jdk</b><b>還是</b><b>guava</b>

<b>對應的</b><b>guava</b><b>工具類</b><b></b>

collection

jdk

list

<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/lists.html">lists</a>

set

<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/sets.html">sets</a>

sortedset

map

<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/maps.html">maps</a>

sortedmap

queue

<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/queues.html">queues</a>

<a href="http://code.google.com/p/guava-libraries/wiki/newcollectiontypesexplained#multiset">multiset</a>

guava

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multisets.html">multisets</a>

<a href="http://code.google.com/p/guava-libraries/wiki/newcollectiontypesexplained#multimap">multimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html">multimaps</a>

<a href="http://code.google.com/p/guava-libraries/wiki/newcollectiontypesexplained#bimap">bimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/maps.html">maps</a>

<a href="http://code.google.com/p/guava-libraries/wiki/newcollectiontypesexplained#table">table</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/tables.html">tables</a>

在找類似轉化、過濾的方法?請看第四章,函數式風格。

在jdk 7之前,構造新的範型集合時要讨厭地重複聲明範型:

<code>1</code>

<code>list&lt;typethatstoolongforitsowngood&gt; list = </code><code>new</code><code>arraylist&lt;typethatstoolongforitsowngood&gt;();</code>

我想我們都認為這很讨厭。是以guava提供了能夠推斷範型的靜态工廠方法:

<code>list&lt;typethatstoolongforitsowngood&gt; list = lists.newarraylist();</code>

<code>2</code>

<code>map&lt;keytype, longishvaluetype&gt; map = maps.newlinkedhashmap();</code>

可以肯定的是,jdk7版本的鑽石操作符(&lt;&gt;)沒有這樣的麻煩:

<code>list&lt;typethatstoolongforitsowngood&gt; list = </code><code>new</code> <code>arraylist&lt;&gt;();</code>

但guava的靜态工廠方法遠不止這麼簡單。用工廠方法模式,我們可以友善地在初始化時就指定起始元素。

<code>set&lt;type&gt; copyset = sets.newhashset(elements);</code>

<code>list&lt;string&gt; theseelements = lists.newarraylist(</code><code>"alpha"</code><code>, </code><code>"beta"</code><code>, </code><code>"gamma"</code><code>);</code>

此外,通過為工廠方法命名(effective java第一條),我們可以提高集合初始化大小的可讀性:

<code>list&lt;type&gt; exactly100 = lists.newarraylistwithcapacity(</code><code>100</code><code>);</code>

<code>list&lt;type&gt; approx100 = lists.newarraylistwithexpectedsize(</code><code>100</code><code>);</code>

<code>3</code>

<code>set&lt;type&gt; approx100set = sets.newhashsetwithexpectedsize(</code><code>100</code><code>);</code>

确切的靜态工廠方法和相應的工具類一起羅列在下面的章節。

注意:guava引入的新集合類型沒有暴露原始構造器,也沒有在工具類中提供初始化方法。而是直接在集合類中提供了靜态工廠方法,例如:

<code>multiset&lt;string&gt; multiset = hashmultiset.create();</code>

在可能的情況下,guava提供的工具方法更偏向于接受iterable而不是collection類型。在google,對于不存放在主存的集合——比如從資料庫或其他資料中心收集的結果集,因為實際上還沒有攫取全部資料,這類結果集都不能支援類似size()的操作 ——通常都不會用collection類型來表示。

下面列出了一些最常用的工具方法,但更多iterables的函數式方法将在第四章讨論。

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#concat(java.lang.iterable)">concat(iterable&lt;iterable&gt;)</a>

串聯多個iterables的懶視圖*

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#concat(java.lang.iterable...)">concat(iterable...)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#frequency(java.lang.iterable,%20java.lang.object)">frequency(iterable, object)</a>

傳回對象在iterable中出現的次數

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#partition(java.lang.iterable,%20int)">partition(iterable, int)</a>

把iterable按指定大小分割,得到的子集都不能進行修改操作

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#getfirst(java.lang.iterable,%20t)">getfirst(iterable, t default)</a>

傳回iterable的第一個元素,若iterable為空則傳回預設值

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#getlast(java.lang.iterable)">getlast(iterable)</a>

傳回iterable的最後一個元素,若iterable為空則抛出nosuchelementexception

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#last()">fluentiterable.last()</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#elementsequal(java.lang.iterable,%20java.lang.iterable)">elementsequal(iterable, iterable)</a>

如果兩個iterable中的所有元素相等且順序一緻,傳回true

與list.equals(object)比較

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#unmodifiableiterable(java.lang.iterable)">unmodifiableiterable(iterable)</a>

傳回iterable的不可變視圖

與collections. unmodifiablecollection(collection)比較

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#limit(java.lang.iterable,%20int)">limit(iterable, int)</a>

限制iterable的元素個數限制給定值

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#limit(int)">fluentiterable.limit(int)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#getonlyelement(java.lang.iterable)">getonlyelement(iterable)</a>

擷取iterable中唯一的元素,如果iterable為空或有多個元素,則快速失敗

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#getonlyelement(java.lang.iterable,%20t)">getonlyelement(iterable, t default)</a>

*譯者注:懶視圖意味着如果還沒通路到某個iterable中的元素,則不會對它進行串聯操作。

<code>iterable&lt;integer&gt; concatenated = iterables.concat(</code>

<code>        </code><code>ints.aslist(</code><code>1</code><code>, </code><code>2</code><code>, </code><code>3</code><code>),</code>

<code>        </code><code>ints.aslist(</code><code>4</code><code>, </code><code>5</code><code>, </code><code>6</code><code>)); </code><code>// concatenated包括元素 1, 2, 3, 4, 5, 6</code>

<code>4</code>

<code>string lastadded = iterables.getlast(mylinkedhashset);</code>

<code>5</code>

<code>string theelement = iterables.getonlyelement(thissetisdefinitelyasingleton);</code>

<code>6</code>

<code>//如果set不是單元素集,就會出錯了!</code>

通常來說,collection的實作天然支援操作其他collection,但卻不能操作iterable。

下面的方法中,如果傳入的iterable是一個collection執行個體,則實際操作将會委托給相應的collection接口方法。例如,往iterables.size方法傳入是一個collection執行個體,它不會真的周遊iterator擷取大小,而是直接調用collection.size。

<b>方法</b><b></b>

<b>類似的</b><b>collection</b><b>方法</b><b></b>

<b>等價的</b><b>fluentiterable</b><b>方法</b><b></b>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#addall(java.util.collection,%20java.lang.iterable)">addall(collection addto,   iterable toadd)</a>

collection.addall(collection)

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#contains(java.lang.iterable,%20java.lang.object)">contains(iterable, object)</a>

collection.contains(object)

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#contains(java.lang.object)">fluentiterable.contains(object)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#removeall(java.lang.iterable,%20java.util.collection)">removeall(iterable   removefrom, collection toremove)</a>

collection.removeall(collection)

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#retainall(java.lang.iterable,%20java.util.collection)">retainall(iterable   removefrom, collection toretain)</a>

collection.retainall(collection)

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#size(java.lang.iterable)">size(iterable)</a>

collection.size()

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#size()">fluentiterable.size()</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#toarray(java.lang.iterable,%20java.lang.class)">toarray(iterable, class)</a>

collection.toarray(t[])

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#toarray(java.lang.class)">fluentiterable.toarray(class)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#isempty(java.lang.iterable)">isempty(iterable)</a>

collection.isempty()

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#isempty()">fluentiterable.isempty()</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#get(java.lang.iterable,%20int)">get(iterable, int)</a>

list.get(int)

<a href="http://docs.guava-libraries.googlecode.com/git-%20history/release12/javadoc/com/google/common/collect/fluentiterable.html#get(int)">fluentiterable.get(int)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/iterables.html#tostring(java.lang.iterable)">tostring(iterable)</a>

collection.tostring()

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#tostring()">fluentiterable.tostring()</a>

除了上面和第四章提到的方法,fluentiterable還有一些便利方法用來把自己拷貝到不可變集合

immutablelist

immutableset

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#toimmutableset()">toimmutableset()</a>

immutablesortedset

<a href="http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/fluentiterable.html#toimmutablesortedset(java.util.comparator)">toimmutablesortedset(comparator)</a>

<b>描述</b><b></b>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/lists.html#partition(java.util.list,%20int)">partition(list, int)</a>

把list按指定大小分割

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/lists.html#reverse(java.util.list)">reverse(list)</a>

<code>list countup = ints.aslist(</code><code>1</code><code>, </code><code>2</code><code>, </code><code>3</code><code>, </code><code>4</code><code>, </code><code>5</code><code>);</code>

<code>list countdown = lists.reverse(thelist); </code><code>// {5, 4, 3, 2, 1}</code>

<code>list&lt;list&gt; parts = lists.partition(countup, </code><code>2</code><code>);</code><code>//{{1,2}, {3,4}, {5}}</code>

lists提供如下靜态工廠方法:

<b>具體實作類型</b><b></b>

<b>工廠方法</b><b></b>

arraylist

linkedlist

直接當作set使用,因為setview也實作了set接口;

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/sets.html#union(java.util.set,%20java.util.set)">union(set, set)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/sets.html#intersection(java.util.set,%20java.util.set)">intersection(set, set)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/sets.html#difference(java.util.set,%20java.util.set)">difference(set, set)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/sets.html#symmetricdifference(java.util.set,%20java.util.set)">symmetricdifference(set,   set)</a>

使用範例:

<code>set&lt;string&gt; wordswithprimelength = immutableset.of(</code><code>"one"</code><code>, </code><code>"two"</code><code>, </code><code>"three"</code><code>, </code><code>"six"</code><code>, </code><code>"seven"</code><code>, </code><code>"eight"</code><code>);</code>

<code>set&lt;string&gt; primes = immutableset.of(</code><code>"two"</code><code>, </code><code>"three"</code><code>, </code><code>"five"</code><code>, </code><code>"seven"</code><code>);</code>

<code>setview&lt;string&gt; intersection = sets.intersection(primes,wordswithprimelength);</code>

<code>// intersection包含"two", "three", "seven"</code>

<code>return</code> <code>intersection.immutablecopy();</code><code>//可以使用交集,但不可變拷貝的讀取效率更高</code>

<b>另請參見</b><b></b>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/sets.html#cartesianproduct(java.util.list)">cartesianproduct(list&lt;set&gt;)</a>

傳回所有集合的笛卡兒積

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/sets.html#cartesianproduct(java.util.set...)">cartesianproduct(set...)</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/sets.html#powerset(java.util.set)">powerset(set)</a>

傳回給定集合的所有子集

<code>set&lt;string&gt; animals = immutableset.of(</code><code>"gerbil"</code><code>, </code><code>"hamster"</code><code>);</code>

<code>set&lt;string&gt; fruits = immutableset.of(</code><code>"apple"</code><code>, </code><code>"orange"</code><code>, </code><code>"banana"</code><code>);</code>

<code>set&lt;list&lt;string&gt;&gt; product = sets.cartesianproduct(animals, fruits);</code>

<code>// {{"gerbil", "apple"}, {"gerbil", "orange"}, {"gerbil", "banana"},</code>

<code>//  {"hamster", "apple"}, {"hamster", "orange"}, {"hamster", "banana"}}</code>

<code>7</code>

<code>8</code>

<code>set&lt;set&lt;string&gt;&gt; animalsets = sets.powerset(animals);</code>

<code>9</code>

<code>// {{}, {"gerbil"}, {"hamster"}, {"gerbil", "hamster"}}</code>

sets提供如下靜态工廠方法:

hashset

linkedhashset

treeset

比方說,我們有一堆字元串,這些字元串的長度都是獨一無二的,而我們希望能夠按照特定長度查找字元串:

<code>immutablemap&lt;integer, string&gt; stringsbyindex = maps.uniqueindex(strings,</code>

<code>    </code><code>new</code> <code>function&lt;string, integer&gt; () {</code>

<code>        </code><code>public</code> <code>integer apply(string string) {</code>

<code>            </code><code>return</code> <code>string.length();</code>

<code>        </code><code>}</code>

<code>    </code><code>});</code>

如果索引值不是獨一無二的,請參見下面的multimaps.index方法。

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/mapdifference.html#entriesincommon()">entriesincommon()</a>

兩個map中都有的映射項,包括比對的鍵與值

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/mapdifference.html#entriesdiffering()">entriesdiffering()</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/mapdifference.html#entriesonlyonleft()">entriesonlyonleft()</a>

鍵隻存在于左邊map的映射項

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/mapdifference.html#entriesonlyonright()">entriesonlyonright()</a>

鍵隻存在于右邊map的映射項

<code>map&lt;string, integer&gt; left = immutablemap.of(</code><code>"a"</code><code>, </code><code>1</code><code>, </code><code>"b"</code><code>, </code><code>2</code><code>, </code><code>"c"</code><code>, </code><code>3</code><code>);</code>

<code>mapdifference&lt;string, integer&gt; diff = maps.difference(left, right);</code>

<code>diff.entriesincommon(); </code><code>// {"b" =&gt; 2}</code>

<code>diff.entriesonlyonleft(); </code><code>// {"a" =&gt; 1}</code>

<code>diff.entriesonlyonright(); </code><code>// {"d" =&gt; 5}</code>

guava中處理bimap的工具方法在maps類中,因為bimap也是一種map實作。

<b>bimap</b><b>工具方法</b><b></b>

<b>相應的</b><b>map</b><b>工具方法</b><b></b>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/maps.html#synchronizedbimap(com.google.common.collect.bimap)">synchronizedbimap(bimap)</a>

collections.synchronizedmap(map)

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/maps.html#unmodifiablebimap(com.google.common.collect.bimap)">unmodifiablebimap(bimap)</a>

collections.unmodifiablemap(map)

maps提供如下靜态工廠方法:

hashmap

linkedhashmap

treemap

enummap

concurrentmap:支援所有操作

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/maps.html#newconcurrentmap()">basic</a>

identityhashmap

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/maps.html#newidentityhashmap()">basic</a>

<b>說明</b><b></b>

<b>和</b><b>collection</b><b>方法的差別</b><b></b>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multisets.html#containsoccurrences(com.google.common.collect.multiset,%20com.google.common.collect.multiset)">containsoccurrences(multiset   sup, multiset sub)</a>

對任意o,如果sub.count(o)&lt;=super.count(o),傳回true

collection.containsall忽略個數,而隻關心sub的元素是否都在super中

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multisets.html#removeoccurrences(com.google.common.collect.multiset,%20com.google.common.collect.multiset)">removeoccurrences(multiset   removefrom, multiset toremove)</a>

對toremove中的重複元素,僅在removefrom中删除相同個數。

collection.removeall移除所有出現在toremove的元素

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multisets.html#retainoccurrences(com.google.common.collect.multiset,%20com.google.common.collect.multiset)">retainoccurrences(multiset   removefrom, multiset toretain)</a>

修改removefrom,以保證任意o都符合removefrom.count(o)&lt;=toretain.count(o)

collection.retainall保留所有出現在toretain的元素

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multisets.html#intersection(com.google.common.collect.multiset,%20com.google.common.collect.multiset)">intersection(multiset,   multiset)</a>

傳回兩個multiset的交集;

沒有類似方法

<code>01</code>

<code>multiset&lt;string&gt; multiset1 = hashmultiset.create();</code>

<code>02</code>

<code>multiset1.add(</code><code>"a"</code><code>, </code><code>2</code><code>);</code>

<code>03</code>

<code>04</code>

<code>multiset&lt;string&gt; multiset2 = hashmultiset.create();</code>

<code>05</code>

<code>multiset2.add(</code><code>"a"</code><code>, </code><code>5</code><code>);</code>

<code>06</code>

<code>07</code>

<code>multiset1.containsall(multiset2); </code><code>//傳回true;因為包含了所有不重複元素,</code>

<code>08</code>

<code>//雖然multiset1實際上包含2個"a",而multiset2包含5個"a"</code>

<code>09</code>

<code>multisets.containsoccurrences(multiset1, multiset2); </code><code>// returns false</code>

<code>10</code>

<code>11</code>

<code>multiset2.removeoccurrences(multiset1); </code><code>// multiset2 現在包含3個"a"</code>

<code>12</code>

<code>multiset2.removeall(multiset1);</code><code>//multiset2移除所有"a",雖然multiset1隻有2個"a"</code>

<code>13</code>

<code>multiset2.isempty(); </code><code>// returns true</code>

multisets中的其他工具方法還包括:

<a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/multisets.html#copyhighestcountfirst(com.google.common.collect.multiset)">copyhighestcountfirst(multiset)</a>

傳回multiset的不可變拷貝,并将元素按重複出現的次數做降序排列

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multisets.html#unmodifiablemultiset(com.google.common.collect.multiset)">unmodifiablemultiset(multiset)</a>

傳回multiset的隻讀視圖

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multisets.html#unmodifiablesortedmultiset(com.google.common.collect.sortedmultiset)">unmodifiablesortedmultiset(sortedmultiset)</a>

傳回sortedmultiset的隻讀視圖

<code>multiset.add(</code><code>"a"</code><code>, </code><code>3</code><code>);</code>

<code>multiset.add(</code><code>"b"</code><code>, </code><code>5</code><code>);</code>

<code>multiset.add(</code><code>"c"</code><code>, </code><code>1</code><code>);</code>

<code>immutablemultiset highestcountfirst = multisets.copyhighestcountfirst(multiset);</code>

<code>//highestcountfirst,包括它的entryset和elementset,按{"b", "a", "c"}排列元素</code>

比方說,我們想把字元串按長度分組。

<code>immutableset digits = immutableset.of(</code><code>"zero"</code><code>, </code><code>"one"</code><code>, </code><code>"two"</code><code>, </code><code>"three"</code><code>, </code><code>"four"</code><code>, </code><code>"five"</code><code>, </code><code>"six"</code><code>, </code><code>"seven"</code><code>, </code><code>"eight"</code><code>, </code><code>"nine"</code><code>);</code>

<code>function&lt;string, integer&gt; lengthfunction = </code><code>new</code> <code>function&lt;string, integer&gt;() {</code>

<code>    </code><code>public</code> <code>integer apply(string string) {</code>

<code>        </code><code>return</code> <code>string.length();</code>

<code>    </code><code>}</code>

<code>};</code>

<code>immutablelistmultimap&lt;integer, string&gt; digitsbylength= multimaps.index(digits, lengthfunction);</code>

<code>/*</code>

<code>*  digitsbylength maps:</code>

<code>*  3 =&gt; {"one", "two", "six"}</code>

<code>*  4 =&gt; {"zero", "four", "five", "nine"}</code>

<code>*  5 =&gt; {"three", "seven", "eight"}</code>

<code>14</code>

<code>*/</code>

<code>arraylistmultimap&lt;string, integer&gt; multimap = arraylistmultimap.create();</code>

<code>multimap.putall(</code><code>"b"</code><code>, ints.aslist(</code><code>2</code><code>, </code><code>4</code><code>, </code><code>6</code><code>));</code>

<code>multimap.putall(</code><code>"a"</code><code>, ints.aslist(</code><code>4</code><code>, </code><code>2</code><code>, </code><code>1</code><code>));</code>

<code>multimap.putall(</code><code>"c"</code><code>, ints.aslist(</code><code>2</code><code>, </code><code>5</code><code>, </code><code>3</code><code>));</code>

<code>treemultimap&lt;integer, string&gt; inverse = multimaps.invertfrom(multimap, treemultimap&lt;string, integer&gt;.create());</code>

<code>//注意我們選擇的實作,因為選了treemultimap,得到的反轉結果是有序的</code>

<code>* inverse maps:</code>

<code>*  1 =&gt; {"a"}</code>

<code>*  2 =&gt; {"a", "b", "c"}</code>

<code>*  3 =&gt; {"c"}</code>

<code>*  4 =&gt; {"a", "b"}</code>

<code>*  5 =&gt; {"c"}</code>

<code>15</code>

<code>*  6 =&gt; {"b"}</code>

<code>16</code>

<code>map&lt;string, integer&gt; map = immutablemap.of(</code><code>"a"</code><code>, </code><code>1</code><code>, </code><code>"b"</code><code>, </code><code>1</code><code>, </code><code>"c"</code><code>, </code><code>2</code><code>);</code>

<code>setmultimap&lt;string, integer&gt; multimap = multimaps.formap(map);</code>

<code>// multimap:["a" =&gt; {1}, "b" =&gt; {1}, "c" =&gt; {2}]</code>

<code>multimap&lt;integer, string&gt; inverse = multimaps.invertfrom(multimap, hashmultimap&lt;integer, string&gt;.create());</code>

<code>// inverse:[1 =&gt; {"a","b"}, 2 =&gt; {"c"}]</code>

multimaps提供了傳統的包裝方法,以及讓你選擇map和collection類型以自定義multimap實作的工具方法。

隻讀包裝

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#unmodifiablemultimap(com.google.common.collect.multimap)">multimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#unmodifiablelistmultimap(com.google.common.collect.listmultimap)">listmultimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#unmodifiablesetmultimap(com.google.common.collect.setmultimap)">setmultimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#unmodifiablesortedsetmultimap(com.google.common.collect.sortedsetmultimap)">sortedsetmultimap</a>

同步包裝

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#synchronizedmultimap(com.google.common.collect.multimap)">multimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#synchronizedlistmultimap(com.google.common.collect.listmultimap)">listmultimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#synchronizedsetmultimap(com.google.common.collect.setmultimap)">setmultimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#synchronizedsortedsetmultimap(com.google.common.collect.sortedsetmultimap)">sortedsetmultimap</a>

自定義實作

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#newmultimap(java.util.map,%20com.google.common.base.supplier)">multimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#newlistmultimap(java.util.map,%20com.google.common.base.supplier)">listmultimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#newsetmultimap(java.util.map,%20com.google.common.base.supplier)">setmultimap</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/multimaps.html#newsortedsetmultimap(java.util.map,%20com.google.common.base.supplier)">sortedsetmultimap</a>

自定義multimap的方法允許你指定multimap中的特定實作。但要注意的是:

multimap假設對map和supplier産生的集合對象有完全所有權。這些自定義對象應避免手動更新,并且在提供給multimap時應該是空的,此外還不應該使用軟引用、弱引用或虛引用。

無法保證修改了multimap以後,底層map的内容是什麼樣的。

即使map和supplier産生的集合都是線程安全的,它們組成的multimap也不能保證并發操作的線程安全性。并發讀操作是工作正常的,但需要保證并發讀寫的話,請考慮用同步包裝器解決。

隻有當map、supplier、supplier産生的集合對象、以及multimap存放的鍵值類型都是可序列化的,multimap才是可序列化的。

multimap.get(key)傳回的集合對象和supplier傳回的集合對象并不是同一類型。但如果supplier傳回的是随機通路集合,那麼multimap.get(key)傳回的集合也是可随機通路的。

請注意,用來自定義multimap的方法需要一個supplier參數,以建立嶄新的集合。下面有個實作listmultimap的例子——用treemap做映射,而每個鍵對應的多個值用linkedlist存儲。

<code>listmultimap&lt;string, integer&gt; mymultimap = multimaps.newlistmultimap(</code>

<code>    </code><code>maps.&lt;string, collection&gt;newtreemap(),</code>

<code>    </code><code>new</code> <code>supplier&lt;linkedlist&gt;() {</code>

<code>        </code><code>public</code> <code>linkedlist get() {</code>

<code>            </code><code>return</code> <code>lists.newlinkedlist();</code>

<code>// 使用linkedhashmaps替代hashmaps</code>

<code>table&lt;string, character, integer&gt; table = tables.newcustomtable(</code>

<code>maps.&lt;string, map&lt;character, integer&gt;&gt;newlinkedhashmap(),</code>

<code>new</code> <code>supplier&lt;map&lt;character, integer&gt;&gt; () {</code>

<code>public</code> <code>map&lt;character, integer&gt; get() {</code>

<code>return</code> <code>maps.newlinkedhashmap();</code>

<code>}</code>

<code>});</code>

unmodifiable

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/tables.html#unmodifiabletable(com.google.common.collect.table)">table</a>

<a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/tables.html#unmodifiablerowsortedtable(com.google.common.collect.rowsortedtable)">rowsortedtable</a>