本文基于jdk1.8.
HashMap即哈希表,是一种能以常数平均时间完成插入,删除和查找操作的数据结构;
哈希表有两种实现方式:开放地址方式和冲突链表方式;开放地址方式不需要使用链表,但是要频繁的再散列操作,常用的再散列方法有线性探测法,平方探测法,双散列法。冲突链表方式将所有哈希值相同的键用链表串起来,理想情况下的哈希表每个哈希值对应一个键,此时查找操作为常数时间;
有两个参数与哈希表的性能有关:容量Capacity和装载因子load_factor,Threshold=Capacity * load_factor;
哈希表默认的容量是2^4;最大容量是2^30;装载因子默认为0.75;
当装入哈希表的元素大于threshold时,哈希表自动扩容,容量变为原来2倍,扩容后元素顺序会被打散,在不同时间遍历哈希表得到的结果可能不同;
在jdk1.8中,链表过长的话(长度>8),HashMap会将冲突链表转化为红黑树;
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
其底层实现是由数组和链表构造而成,如图:
1. get(Object key)
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}通过传入key得到value;
2. getNode(int hash, Object key)
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;
}tab[n-1]&hash是确定key在哈希表中的位置;
然后在链表中寻找(k==key || key.equals(k)),找k是否==key或equals key;返回Node;
若需要将自定义的对象放入HashMap中,需要override equals方法和hashCode方法;
3. containsKey(Object key)
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}判断哈希表中是否存在这个key;
4. put
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}将一个键值对插入哈希表;
5.remove
public V remove(Object key) {
Node<K,V> e;
return (e = removeNode(hash(key), key, null, false, true)) == null ?
null : e.value;
}将key对应的Node从哈希表中删除;
和其他集合类的比较:HashSet采用了适配器模式(HashSet里有一个HashMap);HashMap没有实现同步,HashTable实现了同步,其余类似;HashMap元素无序,TreeMap元素有序;
参考文章:https://zhuanlan.zhihu.com/p/24828513
本文详细介绍了Java中的HashMap数据结构,包括其实现原理、关键方法解析及与其他集合类的区别。深入探讨了HashMap的底层实现机制,如容量、装载因子、冲突解决策略等。
1万+

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



