对于HashMap的table而言,数据分布需要均匀(最好每项都只有一个元素,这样就可以直接通过数据下标直接找到),不能太松,浪费空间。不能太紧,查询变慢。计算hash值后,怎么才能保证table元素分布均匀呢?我们会想到取模,但是由于取模的消耗较大,
HashMap是这样处理的:调用indexFor()方法
static int indexFor(int h, int length) { return h & (length-1); }
返回的是key的hashcode跟哈希表容量-1做与运算。运算的结果便是哈希表中数组的下标。
分析: h:不可控 length-1:可控 准备:与运算:1&1=1; 1&0=0; 0&0=0。 1. 奇数的最后一个二进制位是1,偶数的最后一个二进制位是0。 2. 当length-1为奇数时,无论h是什么数值,结果的二进制最后一位可能是1,也可能是0,则结果可能是正数,也可能是负数。 3. 当length-1为偶数时,无论h是什么数值,结果的二进制位必是0,则结果是必然是偶数。
当length为偶数时,便保证了h&(length-1)结果的最后一个二进制位是0,也可能是1,即结果可能是偶数也可能是奇数。这样便可以保证散列的均匀性!
当length为奇数时,h&(length-1)结果必然是偶数,这样任何hash值都只会被散列到数组的偶数下标上,浪费了一半的数组空间(内存空间)。
所以length取2的整数此幂,是为了使不同hash值发生碰撞的概率较小,使元素在HashMap中均匀散列分布位置。
所以默认的length为16,即2^4。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)