2-1 HashMap-CurrentHashMap
java基础
java集合
JVM
多线程
mysql_数据库
计算机网络
nosql_redis
设计模式
操作系统
消息中间件activeMq
SSM框架面试题
服务中间件Dubbo
注意: 本文设计的原理和源码大部分都是jdk1.8的,不过我会给出1.7的源码。注意查看 我会标记清楚的。
1-HashMap
1-1原理
hashmap是数组+链表或红黑树(1.8新增)结合体,数组的每个元素存储的是链表的头结点。(1.8)向hashmap put值的时候,先取key.hashcode 在hash & length -1计算出数组下标。
if 该下标对应的链表为空,直接把键与值作为链表头节点。不为空,则遍历链表是否存在于key相同的节点,{ 相同,value值替换。 不相同,则放在尾部。1.8
}
1.7是头插法,而1.8是尾插法,待会我给你们解释为什么要这样做。
1-2hash函数的计算
1.8 直接上源码
1.8
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
下图为计算过程 ,对key。

1.7可不是这样的哦 没有 1.8简单,而且1.8更方便易懂。
1.7
final int hash(Object k) {
int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h ^= k.hashCode();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
1-3hashmap参数以及扩容机制
初始容量为 16, 达到阈值扩容, 阈值== 最大容量 * 负载因子(0.75),每次扩容后为原始容量的2倍。
扩容机制 resize()。 使用一个容量更大的数组来代替已有容量小的数组,transfer()方法将原有Entry数组的元素拷贝到新的Entry数组里,jdk1.7要重新计算元素在数组中的位置。 jdk1.8中不是重新计算而是采用了一种更巧妙的方式。
1-4get put源码1.7 1.8 都是没有枷锁
get put 1.8源码
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
// 链表
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
// 红黑树
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length

本文详细解析了HashMap的工作原理,包括其在Java 1.7和Java 1.8版本中的实现差异,探讨了hash函数计算、参数及扩容机制、get与put方法的源码,并深入分析了Java 8对HashMap的改进,如引入红黑树提高性能。
最低0.47元/天 解锁文章
2187

被折叠的 条评论
为什么被折叠?



