今天看了下google开源工具类的源码,主要看了下Multimap的源码,写一下自己阅读中的一些总结。
在JDK中的Map,一个键对应一个值,值可以重复,键不能重复,相同的键会导致值得覆盖,这是最基本的Map的功能。Multimap实现的是一个键对应多个值,通过相同键得到值结果是一个Collection。
引用下源码中对Multimap的描述:
写道
A collection that maps keys to values, similar to {@link Map}, but in which each key may be associated with <i>multiple</i> values. You can visualize the contents of a multimap either as a map from keys to <i>nonempty</i> collections of values
下面是演示一个简单的小示例来说明这个简单的功能:
package com.google.test;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
public class GoogleTest {
public static void main(String[] args) {
Multimap<String, String> loverName = ArrayListMultimap.create();
loverName.put("lover", "翠花");
loverName.put("lover", "凤姐");
System.out.println(loverName.get("lover"));
}
}
结果:[翠花, 凤姐]
Multimap是一个接口,它的实现类有好几种:
①ArrayListMultimap:它是用一个ArrayList来存放给定的键对应的值集合。
ArrayListMultimap中的部分源码:
public final class ArrayListMultimap<K, V> extends AbstractListMultimap<K, V> {
// Default from ArrayList
private static final int DEFAULT_VALUES_PER_KEY = 3;
@VisibleForTesting transient int expectedValuesPerKey;
/**
* Creates a new, empty {@code ArrayListMultimap} with the default initial
* capacities.
*/
public static <K, V> ArrayListMultimap<K, V> create() {
return new ArrayListMultimap<K, V>();
}
private ArrayListMultimap() {
super(new HashMap<K, Collection<V>>());
expectedValuesPerKey = DEFAULT_VALUES_PER_KEY;
}
...(省略)
}
父类AbstractKistMultimap部分源码:
abstract class AbstractListMultimap<K, V>
extends AbstractMapBasedMultimap<K, V> implements ListMultimap<K, V> {
/**
* Creates a new multimap that uses the provided map.
*
* @param map place to store the mapping from each key to its corresponding
* values
*/
protected AbstractListMultimap(Map<K, Collection<V>> map) {
super(map);
}
...(省略)
}
其实最终也就是用AbstractMapBasedMultimap类中的 private transient Map<K, Collection<V>> map去存储的
看到上面的源码就解释了一键对多值的原理了。
知道上面ArrayListMultimap的存储原理, 也就明白各个方法的实现原理了
put 方法的实现源码
public boolean put(@Nullable K key, @Nullable V value) {
return get(key).add(value);
}
通过get得到Map对应value集合,然后add值到集合中。
get方法的实现源码
public Collection<V> get(@Nullable K key) {
Collection<V> collection = map.get(key);
if (collection == null) {
collection = createCollection(key);
}
return wrapCollection(key, collection);
}