标签:哈希 print round 获得 next 红黑树 长度 组成 效率
哈希表是由数组+链表组成的,首先有一个数组,数组的每一个位置都用来存储一个链表,链表的基本节点为:【hash值,key值,value值,next】,当存入一个键值对时,首先调用hashcode()方法获得key的hashcode,然后通过算法计算出hash值,当不同的key取到相同的hash值时,后面的key作为一个节点连接到前一个相同hash值的key的节点。
最差的算法:hashcode/hashcode 会将所有的元素存储在数组的下标1位,实际上已经退化为一个数组
常用的算法是:hashcode%数组长度
通过这个算法将得到[0,数组长度-1]的值,即hash值。这种算法可以使各key尽可能均匀的分布在数组中。这种表也称作“散列(hash的翻译)表”。
优化算法:同样是取余数,但是进行了优化。首先约定数组的长度为2的整数幂,然后通过位运算快速得道hash值:hashcode&(数组长度-1)
下面验算一下算法:
public class Test { public static void main(String[] args) { Test t = new Test(); //算法:hashcode%数组长度,假设数组长度为16(2的4次方) System.out.println(t.hashCode()%16); System.out.println(t.hashCode()&(16-1)); } } 结果: 2 2
后面又优化了一次,是目前使用的hash值算法(我看不懂):
调用get方法时,会通过传入的key值,调用hashCode()方法获得相应的hashCode值,然后同样通过计算获得hash值,与位桶数组(就是hash表的数组)的对应位置的链表逐个进行equals比较,如相同,则返回该value。
equals方法比较的就是hashCode值,如果a.equals(b)为true,那么a与b的hashCode值一直相等。
HashMap的位桶数组,初始大小为16。当位桶数组中的元素到达(0.75*数组length),就重新调整数组大小为原来的2倍。
但扩容很耗时。
当位桶数组的列表长度大于8时,链表会转换为红黑树,这将大大提高查找效率。
48 容器(七)——HashMap底层:哈希表结构与哈希算法
标签:哈希 print round 获得 next 红黑树 长度 组成 效率
原文地址:https://www.cnblogs.com/Scorpicat/p/12021680.html