1.什么是HashMap:
哈希表(HashTable),一种数据结构,用于缓存技术。时间O(1)
其他数据结构:
1.1.数组:
连续存储单元存储。
指定下标查找O(1);
给定值查找O(n);
输出操O(n);
有序数组的话:二分查找,插值法,斐波那契查找O(logn);
1.2.线性链表:
找到结点O(n),处理结点O(1)
1.3.二叉树:
平衡二叉树:O(logn)
2.哈希方法:
将给定元素进行映射,映射到不同的存储位置---->可能造成哈希冲突(即映射到了同一位置)。
2.1解决哈希冲突的方法:
开发定址法:冲突了,顺序寻找下一个位置;
再散列函数法:冲突了,再进行一次映射;
链地址法:HashMap的方法,采用链表+数组;
2.2链地址法:
HashMap的 主干是由Entry数组组成,长度一定是2的次幂
transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
Entry是HashMap的一个静态内部类:
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;//存储指向下一个Entry的引用,单链表结构
int hash;//对key的hashcode值进行hash运算后得到的值,存储在Entry,避免重复计算
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
图来自https://www.cnblogs.com/chengxiao/p/6059914.html
2.3原理:
HashMap是数组+链表的结构,数组是主体,链表是为了解决哈希冲突;
若定位到的entry不含链表,则只需要1次寻址;
若包含链表,则还是需要遍历所在的链表,O(n)
显然链表越少性能越好
2.4二的次幂:
有利于解决哈希冲突问题
由于在进行Hash的方法中,采用了大量的与运算&。
规定长度为2的次幂,可以使数组长度大部分元素为1。只有低位(二进制len中为1的位)才会对Hash地址产生影响
导致结果的唯一性,避免了哈希冲突。
而当数组进行扩容时,规定长度为2的次幂有利于对数组元素的迁移,因为比如16长度变为32,地位还是都是1,已经hash的元素地址还是不变。