目录
1.2 JDK1.7前与JDK1.8下HashMap底层实现原理的区别
1.什么是HashMap?
HashMap基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
1.1 HashMap与HashTable区别
除表格中区别以外,HashMap类与HashTable大致相同
HashMap | HashTable |
多线程下不安全 | 多线程安全 |
ArrayList | Vertor |
键、值允许为null值(接收空值) | 键、值为非null值(不接受控制) |
实现不同步 | 实现同步 |
1.2 JDK1.7前与JDK1.8下HashMap底层实现原理的区别
JDK1.7前 | JDK1.8 |
数组+链表 | 数组+链表+红黑树 |
1.3 HashMap与TreeMap的区别
HashMap | TreeMap |
底层实现:数组+链表+红黑树 | 底层实现:红黑树 |
键(key)、值(value)允许为null值 | 键(key)不允许为null |
键(key)类型要一致 |
2.HashMap底层实现
2.1 数组+链表+红黑树的底层实现
- 数组优点:通过数组下标可以快速实现对数组元素的访问,效率极高;
- 链表优点:插入或删除数据不需要移动元素,只需修改节点的引用,效率极高。
源码
数组-->HashMap使用数组存储数据,数组中每个元素的类型为Node<K,V> 。
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;//键
V value;//值
Node<K,V> next;next指向链表的下一个节点
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}
2.2 jdk1.8以前HashMap存在的问题
HashMap通过 hash()&(n-1)-->key在数组中存放的下标。当两个key在数组中存放的下标一致时,数组将以链表方式存储(哈希冲突、哈希碰撞)。因而在链表查找一层层往下查找,知道找到,时间复杂度会O(N),所以链表长度越长,HashMap的效率会越来越低。
2.3 解决方法-->JDK1.8底层实现
JDK1.8底层实现为数组+链表+红黑表来实现HashMap。即当链表中的元素超过8个(TREEIFY_THRESHOLD)并且数组长度大于64(MIN_TREEIFY_CAPACITY)时,会将链表转换为红黑树,转换后的数组查询时间复杂度为O(logN)。
源码
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
TreeNode<K,V> parent; // red-black tree links
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev; // needed to unlink next upon deletion
boolean red;
TreeNode(int hash, K key, V val, Node<K,V> next) {
super(hash, key, val, next);
}
......
}
3.HashMap中重要的变量及问题
3.1 变量
//数组的默认容量--16
static