Multimap
参考
工作中频繁的要实现Map\
a -> 1
a -> 2
b -> 3
- 可将其视为单值key到一个collection,正如:
a -> [1, 2, 4]
b -> [3]
c -> [5]
其中第一种的理解更恰当,下面的分析基于此。
Construction
最常使用的是ListMultimap
和 SetMultimap
, keys分别map到List和Set
Construction
创建Multimap最直接的方法是用MultimapBuilder,可以直接配置keys和values的形式:
// creates a ListMultimap with tree keys and array list values
ListMultimap<String, Integer> treeListMultimap =
MultimapBuilder.treeKeys().arrayListValues().build();
// creates a SetMultimap with hash keys and enum set values
SetMultimap<Integer, MyEnum> hashEnumMultimap =
MultimapBuilder.hashKeys().enumSetValues(MyEnum.class).build();
也可以用实现类的create()
方法,相比更推荐使用MultimapBuilder
Modifying
[Multimap.get(key)](http://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/Multimap.html#get-K-)
返回响应key的values的一个view。对于ListMultimap
返回List,对于SetMultimap
返回Set
修改Multimap
:
Set<Person> aliceChildren = childrenMultimap.get(alice);
aliceChildren.clear();
aliceChildren.add(bob);
aliceChildren.add(carol);
其他修改方法
Signature | Description | Equivalent |
---|---|---|
put(K,V) | 添加一个value | multimap.get(key).add(value) |
putAll(K, Iterable) | 在key下放入每个values | Iterables.addAll(multimap.get(key), values) |
remove(K, V) | 从key下移除一个value | multimap.get(key).remove(value) |
removeAll(K) | Removes all values associated with the key key.Once this method returns, key will not be mapped to any values, so it will not appear in keySet(), asMap(), or any other views. | multimap.get(key).clear() |
replaceValues(K, Iterable) | multimap.get(key).clear(); Iterables.addAll(multimap.get(key), values) |
Views
支持一些很有用的views:
- asMap 将
Multimap<K, V>
视为Map<K, Collection<V>>
,返回这个Map支持remove
,可以修改返回的这个map,但不支持put
、putAll
。对于不存在key asMap().get(key)将返回null。不可将asMap.get(key)的返回值cast成为对于Set–>SetMultimap
,对于List–>ListMulitmap
,不支持从ListMultimap
到Map
Multimap Is Not A Map
Multimap.get(key)
返回non-null,可能是一个空的collection,为了让我们可以放入我们想放入的值- 如果更想像Map 一样,返回null,使用
asMap
返回一个Map<K, Collection<V>>
Multimap.containsKey(key)
只有在该key确实有对应的values时才返回trueMultimap.entries()
返回Multimap
的所有keys的entries,如果想返回所有key-collection entries,使用asMap.entrySet()
Multimap.size()
返回所有entries的数,不是keys去重数,若需要,使用Multimap.keySet().size()
返回keys去重数
Implementations
提供很多实现类,在使用Map<K, Collection<V>>
的场景中选择使用
Implementation | Keys behave like… | Values behave like.. |
---|---|---|
ArrayListMultimap | HashMap | ArrayList |
HashMultimap | HashMap | HashSet |
LinkedListMultimap * | LinkedHashMap“* | LinkedList“* |
LinkedHashMultimap** | LinkedHashMap | LinkedHashSet |
TreeMultimap | TreeMap | TreeSet |
ImmutableListMultimap | ImmutableMap | ImmutableList |
ImmutableSetMultimap | ImmutableMap | ImmutableSet |
除了immutable实现,其他实现支持null keys和values
\* LinkedListMultimap.entries()
保留non-distinct key values的迭代顺序
** LinkedHashMultimap
保留keys 和values的插入顺序
API
应用示例
package com.learn.google.guava.ImmutableCollections;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Multiset;
import java.util.Map;
public class MultimapTest {
public static void main(String[] args) {
ListMultimap<String, String> hashArrayListMultimap = MultimapBuilder.hashKeys().arrayListValues().build();
hashArrayListMultimap.put("beijing","haidian");
hashArrayListMultimap.put("beijing","chaoyang");
hashArrayListMultimap.put("shannxi","xi'an");
for (Map.Entry<String, String> entry : hashArrayListMultimap.entries()) {
System.out.println("key = " + entry.getKey() + "--->" + "value=" + entry.getValue() );
}
Multiset<String> keys = hashArrayListMultimap.keys();
System.out.print("\nkeys[");
for (String key : keys) {
System.out.print(key + " ");
}
System.out.println("]");
//输出:
//key = shannxi--->value=xi'an
//key = beijing--->value=haidian
//key = beijing--->value=chaoyang
//keys[shannxi beijing beijing ]
}
}