MultiMap
类关系
ArrayListMultiMap.java
Multimap <I>
|
|
AbstractMultimap <A> Serializable <I>
|__________________________________________|
|
AbstractMapBasedMultimap <A>
|
|
AbstractListMultimap <A> ListMultimap <I>
|__________________________________________|
|
ArrayListMultiMap
LinkedListMultiMap.java
Multimap <I>
|
|
AbstractMultimap <A> ListMultimap <I> Serializable <I>
|__________________________________________|______________________________|
|
LinkedListMultimap
TreeMultimap.java
Multimap <I>
|
|
AbstractMultimap <A> Serializable <I>
|__________________________________________|
|
AbstractMapBasedMultimap <A> SetMultimap <I>
|__________________________________________|
|
AbstractSetMultimap <A> SortedSetMultimap <I>
|__________________________________________|
|
AbstractSortedSetMultimap <A>
|
|
AbstractSortedKeySortedSetMultimap <A>
|
|
TreeMultimap
实现方法
ArrayListMultimap
ArrayListMultiMap.java是以ArrayList为Collection的特定实现,这个类中没有太多的实际代码,主要是createCollection()方法中特定的产生一个ArrayList作为Collection。
AbstractListMultimap.java是AbstractMultimap的一个List专有版本,这个类和ListMultimap接口一起,将Multimap的方法都重写为List。
AbstractMapBasedMultimap.java则是所有以Map为核心的Multimap的基本实现,这里实现了所有Multimap的方法,是最重要的一部分。
clear方法,先将每个collection清空,再把map清空
public void clear() {
// Clear each collection, to make previously returned collections empty.
for (Collection<V> collection : map.values()) {
collection.clear();
}
map.clear();
totalSize = 0;
}
put方法,我们可以发现这里的size是每多一个KV对就加1,而不是唯一Key的数量,这点和Map不同
public boolean put(@Nullable K key, @Nullable V value) {
Collection<V> collection = map.get(key);
// 如果这是一个新key没有对应的Collection
if (collection == null) {
// 先根据子类实现创建一个相应的Collection
collection = createCollection(key);
// 将KV对加入Map中
if (collection.add(value)) {
totalSize++;
map.put(key, collection);
return true;
} else {
throw new AssertionError("New Collection violated the Collection spec");
}
// 如果已经有这个key了,就加入它的Collection
} else if (collection.add(value)) {
totalSize++;
return true;
} else {
return false;
}
}
removeAll方法,需要返回删除的Value,所以要一个临时变量存起来
public Collection<V> removeAll(@Nullable Object key) {
// 先将Key移出
Collection<V> collection = map.remove(key);
// 如果Value为空,则返回空集合
if (collection == null) {
return createUnmodifiableEmptyCollection();
}
// 否则将Value的值拷贝到输出集合中,再把Value清空
Collection<V> output = createCollection();
output.addAll(collection);
totalSize -= collection.size();
collection.clear();
// 返回输出集合
return unmodifiableCollectionSubclass(output);
}
size方法,注意这里返回的是KV数,而非K的唯一个数
public int size() {
return totalSize;
}
isEmpty方法,判断KV数是否为0
public boolean isEmpty() {
return size() == 0;
}
get方法
public Collection<V> get(@Nullable K key) {
Collection<V> collection = map.get(key);
// 如果没有Value就新建一个Collection
if (collection == null) {
collection = createCollection(key);
}
return wrapCollection(key, collection);
}
AbstractMultimap.java也实现了一些基本方法,和上一个文件一起涵盖了所有API
remove方法
public boolean remove(@Nullable Object key, @Nullable Object value) {
// 从Map中按照key找到该集合
Collection<V> collection = asMap().get(key);
// 如果集合不为空,则找到集合中的这个值并删除
return collection != null && collection.remove(value);
}
putAll方法,以key为第一参数,以一个Iterable为第二参数
public boolean putAll(@Nullable K key, Iterable<? extends V> values) {
checkNotNull(values);
// make sure we only call values.iterator() once
// and we only call get(key) if values is nonempty
if (values instanceof Collection) {
Collection<? extends V> valueCollection = (Collection<? extends V>) values;
// 拿出Collection然后把新的addAll进去
return !valueCollection.isEmpty() && get(key).addAll(valueCollection);
} else {
Iterator<? extends V> valueItr = values.iterator();
// 拿出Iterator然后把新的addAll进去
return valueItr.hasNext() && Iterators.addAll(get(key), valueItr);
}
}
putAll方法,以另一个Multimap为参数
public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
boolean changed = false;
for (Map.Entry<? extends K, ? extends V> entry : multimap.entries()) {
changed |= put(entry.getKey(), entry.getValue());
}
return changed;
}
replace方法
public Collection<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
checkNotNull(values);
// 先移除所有
Collection<V> result = removeAll(key);
// 在加入新的值
putAll(key, values);
return result;
}
containsValue方法
public boolean containsValue(@Nullable Object value) {
// 检查每一个Collection是否有这个值
for (Collection<V> collection : asMap().values()) {
if (collection.contains(value)) {
return true;
}
}
return false;
}
containsEntry方法,实际上是用get来判断是否有这个key,然后再看是否有这个值
public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
Collection<V> collection = asMap().get(key);
return collection != null && collection.contains(value);
}
MultiMap的更多相关文章
- C++ std::multimap
std::multimap template < class Key, // multimap::key_type class T, // multimap::mapped_type class ...
- Guava学习笔记:Guava新增集合类型-Multimap
在日常的开发工作中,我们有的时候需要构造像Map<K, List<V>>或者Map<K, Set<V>>这样比较复杂的集合类型的数据结构,以便做相应的业 ...
- [Google Guava]学习--新集合类型Multimap
每个有经验的Java程序员都在某处实现过Map<K, List<V>>或Map<K, Set<V>>,并且要忍受这个结构的笨拙. 假如目前有个需求是给两 ...
- 4.3 map和multimap
使用map multimap必须包含头文件map *:multimap 1)multimap定义 template<class Key,class Pred=less<Key>,cl ...
- STL中的map/multimap小结
(1)使用map/multimap之前必须包含头文件<map>:#include<map> 并且和所有的关联式容器一样,map/multimap通常以平衡二叉树来完成 (2)n ...
- 问题解决——multimap中统计key的种类
================声明================= 本文原创,转载请注明出处和作者,并保持文章的完整性. 本文链接:http://www.cnblogs.com/wlsandwho ...
- STL之multimap
参见http://www.cplusplus.com/reference/map/multimap/ 多重映射multimap和map映射很相似,但是multimap允许重复的关键字,这使得multi ...
- 使用multimap创建重复键关联容器
在“使用 <map> 库创建关联容器”一文中,我们讨论了标准库中的 map 关联容器.但那只是 map 容器的一部分.标准库还定义了一个 multimap 容器,它与 map 类似,所不同 ...
- STL学习系列九:Map和multimap容器
1.map/multimap的简介 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. map中key值是唯一的.集合中的元素按一定的顺 ...
随机推荐
- 转载网页博客:ie7bug:div容器下的img与div存在间隙
1.代码及在浏览器上的显示 ie7: ie8+: Firefox: Chrome: 可以看出ie7上在div容器下添加img,div与img中有间隙,而在ie8+和其他浏览器上均显示正常 网页源代码如 ...
- lines---hdu5124(离散化+数组模拟)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5124 就是有n条在x轴的线段,给你线段的左右端点,每条线段都会覆盖点,求出最多被覆盖多少次: #inc ...
- JVM垃圾回收机制总结(5) :JDK垃圾收集器的配置命令
以下配置主要针对分代垃圾回收算法而言. 堆大小设置 年轻代的设置很关键 JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理 ...
- Android 常用时间格式转换代码
/** * 获取现在时间 * * @return 返回时间类型 yyyy-MM-dd HH:mm:ss */ public static Date getNowDate() { Date curren ...
- 高性能jdbc封装工具 Apache Commons DbUtils 1.6(转载)
转载自原文地址:http://gao-xianglong.iteye.com/blog/2166444 前言 关于Apache的DbUtils中间件或许了解的人并不多,大部分开发人员在生成环境中更多的 ...
- Java基础复习之二:运算符,键盘录入,流程控制语句,if语句,三元运算
1.运算符 1.1.算术运算符 +(加法有三个用法:加法,正号,字符串连接符) - * / % ++ -- 1.1.1./ 是取商,%是取余 1.1.2.++ 与--的用法(a:作用是自 ...
- scroll 事件绑定
var animateBlock={ isVisiable:function(el,wh,st,delta){ delta=delta||200; ...
- 谈谈Perforce
实习就要结束了,收获之一就是学会了使用Perforce! Perforce SCM System是一款构建于可伸缩客户/服务器结构之上的软件配置管理工具.仅仅应用 TCP/IP,开发人员就能够通过多种 ...
- 径向基函数(RBF)神经网络
RBF网络能够逼近任意的非线性函数,可以处理系统内的难以解析的规律性,具有良好的泛化能力,并有很快的学习收敛速度,已成功应用于非线性函数逼近.时间序列分析.数据分类.模式识别.信息处理.图像处理.系统 ...
- 《OD学hadoop》第一周0625 LINUX作业一:Linux系统基本命令(一)
1. 1) vim /etc/udev/rules.d/-persistent-net.rules vi /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE= ...