版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dancheng1/article/details/85256876
Multimap相对于传统的Map区别在于,Multimap是一对多的一个数据结构,对于Multimap的解析用HashMultimap进行解析,看一下HashMultimap的类结构图:
HashMultimap构造器
因为他的构造方法是私有的,所有他会拥有静态方法构造器:
public static <K, V> HashMultimap<K, V> create() {
//new一个HashMultimap,不传入任何值
return new HashMultimap();
}
public static <K, V> HashMultimap<K, V> create(int expectedKeys, int expectedValuesPerKey) {
//new一个HashHultimap,传入两个值,一个是期望key的长度,另一个是期望value的长度
return new HashMultimap(expectedKeys, expectedValuesPerKey);
}
public static <K, V> HashMultimap<K, V> create(Multimap<? extends K, ? extends V> multimap) {
//传入一个Multimap值
return new HashMultimap(multimap);
}
看到了三个静态构造方法之后,了解到三个构造方法都调用了私有的构造器,所以看一下私有构造器的源码:
private HashMultimap() {
//new一个新的map然后交给父类处理
super(new HashMap());
}
private HashMultimap(int expectedKeys, int expectedValuesPerKey) {
//获取一个长度为4/3的expectedKeys 的map然后交给父类处理
super(Maps.newHashMapWithExpectedSize(expectedKeys));
Preconditions.checkArgument(expectedValuesPerKey >= 0);
this.expectedValuesPerKey = expectedValuesPerKey;
}
private HashMultimap(Multimap<? extends K, ? extends V> multimap) {
//获取一个长度为4/3multimap的长度的map交给父类处理
super(Maps.newHashMapWithExpectedSize(multimap.keySet().size()));
this.putAll(multimap);
}
可以看到三个私有构造方法都调用了父类的构造方法,接下来看看父类的构造器源码,发现最后的Multimap的数据结构也体现在AbstractMapBasedMultimap这个类中,所以看一下这个类的构造器个变量:
//底层数据结构是一个key为一个Object类,value为一个容器
private transient Map<K, Collection<V>> map;
//Multimap总长度
private transient int totalSize;
protected AbstractMapBasedMultimap(Map<K, Collection<V>> map) {
Preconditions.checkArgument(map.isEmpty());
this.map = map;
}
功能方法
看到了AbstractMapBasedMultimap的源码发现Multimap的put、get逻辑也是在这个类中实现的:
put方法的实现
public boolean put(@Nullable K key, @Nullable V value) {
//首先在map容器中查看是否有这个key值存在。
Collection collection = (Collection)this.map.get(key);
//如果collection为null,则说明这个key值在map容器中不存在
if(collection == null) {
//根据这个key创建一个容器
collection = this.createCollection(key);
//然后将value放在这个容器中
if(collection.add(value)) {
++this.totalSize;
this.map.put(key, collection);
return true;
} else {
throw new AssertionError("New Collection violated the Collection spec");
}
//如果这个容器存在则直接放入value值
} else if(collection.add(value)) {
++this.totalSize;
return true;
} else {
return false;
}
}
get方法的实现
public Collection<V> get(@Nullable K key) {
//首先在map容器中查看是否有这个key值存在。
Collection collection = (Collection)this.map.get(key);
//如果为null,则为其创建一个容器
if(collection == null) {
collection = this.createCollection(key);
}
//根据本类的wrapCollection方法找到并返回一个集合类
return this.wrapCollection(key, collection);
}