HashMap
- HashMap中允许存放null键null值
- 线程不安全 –线程不同步
- 与HashTable类似
- Hashset是HashMap的实例 HashMap的底层是HashTable哈希表
5.在Java中 HashTable的父类是Dictionary
HashMap底层原理
1.基于Map接口实现 元素以键值对的方式存储
2.可以存储null键和null值 key不能够重复的 null只能有一个null键
3.HashMap不能够保证元素的顺序 无序的
4.线程不安全的
HashMap继承关系
HashMap 继承 AbstractMap<K,V>
HashTable 继承 Dictionary
Map接口<K,V> entry<K,V>是Map接口的内部接口
主要属性:
初识容量 —16
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
最大容量 1*2的30次方
static final int MAXIMUM_CAPACITY = 1 << 30;
加载因子
static final float DEFAULT_LOAD_FACTOR = 0.75f;
HashMap.hashcode算法
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
HashMap 初识容量为16 HashTable 初识容量为11 加载因子都默认为0.75
HashTable扩容方式:Capacity*2 + 1
HashTable hash计算方式: key的hashcode 对table数组的长度进行取模
HashMap的 hash计算方式: key 的hashcode 进行了二次hash 为了能够得到更好的散列值
HashTable的扩容方法
@SuppressWarnings("unchecked")
protected void rehash() {
int oldCapacity = table.length;
Entry<?,?>[] oldMap = table;
// overflow-conscious code
int newCapacity = (oldCapacity << 1) + 1;
if (newCapacity - MAX_ARRAY_SIZE > 0) {
if (oldCapacity == MAX_ARRAY_SIZE)
// Keep running with MAX_ARRAY_SIZE buckets
return;
newCapacity = MAX_ARRAY_SIZE;
}
Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];
modCount++;
//阀值
threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
table = newMap;
for (int i = oldCapacity ; i-- > 0 ;) {
for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
Entry<K,V> e = old;
old = old.next;
int index = (e.hash & 0x7FFFFFFF) % newCapacity;
e.next = (Entry<K,V>)newMap[index];
newMap[index] = e;
}
}
}