基于JDK1.7进行源码解读
HashMap类图与方法

HashMap中的属性


HashMap中的构造方法




HashMap中的put方法




HashMap中的get方法



并发修改和迭代操作


删除操作源码(截图不全,走文字描述)
/**
* Removes and returns the entry associated with the specified key
* in the HashMap. Returns null if the HashMap contains no mapping
* for this key.
*/
final Entry<K,V> removeEntryForKey(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
//计算数组下标后将头结点赋值给前驱结点
Entry<K,V> prev = table[i];
//将前驱结点赋值给临时变量结点e,这个e结点就是要删除的节点
Entry<K,V> e = prev;
//对临时变量结点e进行遍历
while (e != null) {
Entry<K,V> next = e.next;
Object k;
//如果满足if条件则说明找到要删除的节点了
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
//增加修改次数
modCount++;
//将数组大小减1
size--;
if (prev == e)
//如果前驱结点与当前节点一样,就是说链表第一个节点是要删除的数据,直接将
//第一个节点的下一个节点作为链表的第一个节点
table[i] = next;
else
//这里说明链表的第一个节点不是要删除的节点,直接将前驱节点的下一个节点指向到当前节点的下一个节点,就完成了
//删除目标节点的操作
prev.next = next;
//标记这个k-v是删除状态
e.recordRemoval(this);
return e;
}
//没找到就先记录前驱结点为当前阶段
prev = e;
//下一个节点为当前节点
e = next;
}
return e;
}
HashMap中的扩容操作



总结
- 基于jdk1.7实现的HashMap的数据结构就是数组(table)+链表(entry),数组中的元素是是entry链表的头结点.
- HashMap的key-value都可以为空,且对这种情况做了特别的处理
- HashMap存在并发修改和死链问题,大数据量+多线程下不安全,建议使用ConcurrentHashMap
- 扩容的时候链表中的元素会被打乱已有位置和顺序,根据扩容的新的位置进行重新组织数据
- 1.7版本HashMap的源码还是比较少,也稍微好分析的,大概1180行,这里选取比较核心的方法和常用操作进行源码分析。
- 相关链接https://www.jianshu.com/p/4aa3bb16f36c
- 相关链接https://www.cnblogs.com/yangyongjie/p/11015174.html
网友评论