Java:HashMap的总结

HashMap

HashMap综合了数组和链表的优点,是一个查询,插入删除都容易的数据结构。
(1)创建步骤
①通过hash算法,找到与key对应的存储位置
②访问该位置的value,与当前的value的比较,如果相等就返回,不相等找这个位置对应的链表中的值。

(2)哈希冲突的解决:
①链地址法:key一样的插入元素就链接到那个结点之后。(数组和链表的结合)
Java:HashMap的总结

②开放地址法:在插入一个元素的时候,先hash()一下,若是发生哈希冲突,就以当前地址为基准,进行再寻址,若发生冲突再去寻找,直至找到一个为空的地址为止。所以这种方法又称为再散列法。

1)顺序寻址:顺序查看当前table,直到找到当前table的下一个空位;
2)二次寻址:以二次幂查看当前table,直到找到当前的下一个空位。

③公共溢出法:一旦由哈希函数得到的地址冲突,就都填入溢出表。所以也就是将其分为哈希表和公共溢出区两个部分。

(4)红黑树:原先当链表中结点大于等于8时,会把链表变成一棵红黑树,小于6时又会转成链表,但是现在通常不这么做了。

(5)hashCode():hashCode实际指的是某一个对象的内存地址返回的一个int型。

(6)rehash() : 之所以要rehash是因为扩容后hash中因为用到了table.length,所以hash出的值一定不一样了,所以要重新hash。
rehash之后可能是:
1)还在那个Index;
2)index+原来table.length

(7)HashTable和HashMap的联系与区别:

1)实现类、实现接口:
HashMap继承自AbstractMap,HashTable继承自Dictionnary;
实现接口都是Map、Cloneable、Serializable。

2) 默认容量:
HashMap:16
HashTable:11

3)构造函数:
HashMap在第一次put的时候初始化table
HashTale构造函数中初始化table

4)put方法:

HashMap HashTable
是非同步方法 是同步方法
key/value可为null key/value不能为null
2倍方式扩容 2倍+1方式扩容(奇数)
rehash table中从后往前去遍历,对每一个位置的每一个节点进行rehash,连接到新的位置
(该key不存在)尾插 头插

5)hash算法的差异:
HashMap:
hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
index = hash & table.length-1;
HashTable:
index = (e.hash & 0x7FFFFFFF) % Capacity;

(8)WeakHashMap: 可以增加内存利用率,用的是弱引用,不用的可以回收。