简体   繁体   English

HashMap如何确保使用key的hashcode计算的索引在可用范围内?

[英]How does HashMap make sure the index calculated using hashcode of key is within the available range?

I went through source code of HashMap and have a few questions. 我浏览了HashMap的源代码,并提出了一些问题。 The PUT method takes the Key and Value and does PUT方法采用Key和Value

  1. the hashing function of the hashcode of the key. 密钥哈希码的哈希函数。
  2. calculate bucket location for this pair using the hash obtained from the previous step 使用从上一步骤获得的哈希计算该对的桶位置

     public V put(K key, V value) { int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); ..... } static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } static int indexFor(int h, int length) { return h & (length-1); } 

Example: 例:

  • Creating a HashMap with size 10. 创建大小为10的HashMap。
  • call put(k,v) three times and assume these 3 occupies bucket loc 7 ,8 and 9 call put(k,v)三次并假设这3个占用桶位7,8和9
  • call put 4th K,V pair and following happens 呼叫放入第4 K,V对以及后续发生
    • hash() is called with key.hashcode() and hash calculated 使用key.hashcode()调用hash()并计算哈希值
    • indexFor is calculated based on hash indexFor基于哈希计算

Question: 题:

  1. What if the calculated bucket location for the 4th k,v is out of the existing bounds? 如果计算出的第4个k,v的存储区位置超出现有边界怎么办? say location 11 ? 说位置11?

Thanks in advance Akh 在此先感谢Akh

For your first question: the map always uses a power of two for the size (if you give it a capacity of 10, it will actually use 16), which means index & (length - 1) will always be in the range [0, length) so it's always in range. 对于你的第一个问题:地图总是使用2的幂作为大小(如果你给它一个10的容量,它实际上将使用16),这意味着index & (length - 1)将始终在[0, length)的范围内[0, length)所以它总是在范围内。

It's not clear what your second and third question relate to. 目前尚不清楚你的第二个和第三个问题是关于什么的。 I don't think HashMap reallocates everything unless it needs to. 我不认为 HashMap重新分配所有内容,除非它需要。

HashMaps will generally use the hash code mod the number of buckets. HashMaps通常会使用散列码来修改桶的数量。 What happens when there is a collision depends on the implementation (not sure for Java's HashMap). 发生冲突时会发生什么取决于实现(对Java的HashMap不确定)。 There are two basic strategies: keeping a list of items that fall in the bucket, or skipping forward to other buckets if your bucket is full. 有两种基本策略:保留存储桶中的项目列表,或者如果存储桶已满,则跳转到其他存储桶。 My guess would be that HashMap uses the list bucket approach. 我的猜测是HashMap使用列表桶方法。

Let's go into more detail, How hashmap will initialize bucket size? 让我们更详细一点,hashmap如何初始化桶大小?

following code is from HashMap.java 以下代码来自HashMap.java

while (i < paramInt) i <<= 1; while(i <paramInt)i << = 1;

If you pass initial 10 then above code is used to make a size of power 2. So using above code HashMap initialize bucket size 16; 如果你传递的是10,那么上面的代码用来表示权力2.所以使用上面的代码HashMap初始化桶大小16;

And below code is used to calculate bucket index, 以下代码用于计算桶索引,

static int indexFor(int h, int length) {
        return h & (length - 1);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM