前面已经说了HashMap是Map的实现类,线程不安全,效率高。允许null键和null值,是基于哈希表的Map接口实现。哈希表的作用是用来保证键的唯一性的。
常用实例化方法:
new HashMap< Object, Object>();
构造函数:
数据结构:
从上图我们可以发现哈希表是由【数组+链表】组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。
那么这些元素是按照什么样的规则存储到数组中呢?
一般情况是通过【hash(key)%len】获得,也就是元素的key的哈希值对数组长度取模得到。
比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。
存数据逻辑:
首先根据key计算hash值,然后根据hash值存到以hash值为索引的位置。
int hash = key.hashCode(); // 每个key的hash是一个固定的int值
int index = hash % Entry[].length;// 去模运算,运算后的值肯定在0-length之间
Entry[index] = value;// 以去模后的值为索引,把value存进去
可是当hash值一样时,怎么存呢?
其实每个Entity类里面都有key,value,next属性,next作用是指向下一个Entity。当两个key的hash值相同时,得到的index也是相同的,首先判断两个key是否相同,相同的话直接覆盖,不相同的话就:比如第一个键进来,通过计算key的hash值得到index=0,所以Entity[0]=A,然后有一个键B进来,通过计算key的hash得到的index也是为0,那么就会将B.next=A,Entiry[0]=B。所以就将A,B两个Entity连接起来放到Entity[0]中。
取数据: