简体   繁体   English

为什么HashMap和Hastable方法有区别?

[英]Why there is difference in HashMap and Hastable method of put?

I was wondering for put method difference in HashMap and Hashtable 我想知道在HashMapHashtable put方法差异

HashTable put method code HashTable放置方法代码

Entry tab[] = table;
     int hash = key.hashCode();
     int index = (hash & 0x7FFFFFFF) % tab.length;
     for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
         if ((e.hash == hash) && e.key.equals(key)) {
             V old = e.value;
             e.value = value;
             return old;
         }
     }

HashMap put method code HashMap放入方法代码

int hash = hash(key.hashCode());
     int i = indexFor(hash, table.length);
     for (Entry<K,V> e = table[i]; e != null; e = e.next) {
         Object k;
         if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
             V oldValue = e.value;
             e.value = value;
             e.recordAccess(this);
             return oldValue;
         }
     }

why hashtable has different code for finding index? 为什么hashtable有不同的代码来查找索引?

int index = (hash & 0x7FFFFFFF) % tab.length;

while hashMap has hash() function provided by jdk designers. 而hashMap具有jdk设计者提供的hash()函数。

What is 0x7FFFFFFF in binary? 什么是二进制的0x7FFFFFFF It's 01111111111111111111111111111111 . 这是01111111111111111111111111111111

Note that the leftmost bit is 0 . 请注意,最左边的0 That means that the number is always positive (Since the leftmost bit is zero). 这意味着该数字始终为正(因为最左边的为零)。 Because of the & , every number that'll be & -ed with this binary will be non-negative since: 由于中& ,每一个会数量&此二进制-ed将非负的 ,因为:

01111111111111111111111111111111
Anything                          &
--------------------------------
0 ← Always

After this, the % operator is used to ensure that we are in the range of tab.length . 在此之后, %运算符用于确保我们处于tab.length范围内。

You didn't post the implementation of how HashMap generates the index. 您没有发布HashMap如何生成索引的实现。 I don't think it's very different. 我不认为这是非常不同的。 After all they have a very similar logic. 毕竟他们有一个非常相似的逻辑。

HashMap calls indexFor which is doing: return h & (length-1); HashMap调用indexFor执行: return h & (length-1);

Important note: HashTable is older than HashMap , it's no wonder that there are difference implementations. 重要提示: HashTableHashMap旧,难怪存在差异实现。

HashTable: 哈希表:

int index = (hash & 0x7FFFFFFF) % tab.length;

which means: hash - without the leftmost bit (sign) modulo the table length 这意味着:hash - 没有最左边的位(符号)模数表的长度

HashMap: HashMap的:

int i = indexFor(hash, table.length);

is calling: 正在打电话:

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

which means modulo length-1 not a big difference there, and actually modulo length-1 means that the maximum value we can get is length-2. 这意味着模数长度-1在那里没有很大差异,实际modulo length-1意味着我们可以得到的最大值是长度-2。 Here, the length-1 assures that we won't run into a scenario we'll get 0xFFFFFFFF and actually the highest value we might get will be 0xFFFFFFFE . 在这里,length-1确保我们不会遇到我们将获得0xFFFFFFFF ,实际上我们可能获得的最高值将是0xFFFFFFFE

The difference is in the lower bits (in HashMap vs. Higher bits in HashTable). 区别在于低位(在HashMap中与HashTable中的高位相对)。 And now we should ask (recursively) why is that. 现在我们应该(递归地)问为什么。 And the answer is hiding in the hash() method which appears in the first row of the code (above) and which also differs from the HashTable implementation: 答案隐藏在hash()方法中,该方法出现在代码的第一行(上面)中,它也与HashTable实现不同:

int hash = hash(key.hashCode());

and the explanation is found in the hash() method : 并在hash()方法中找到解释:

           /**
  258      * Applies a supplemental hash function to a given hashCode, which
  259      * defends against poor quality hash functions.  This is critical
  260      * because HashMap uses power-of-two length hash tables, that
  261      * otherwise encounter collisions for hashCodes that do not differ
  262      * in lower bits. Note: Null keys always map to hash 0, thus index 0.
  263      */
  264     static int hash(int h) {
  265         // This function ensures that hashCodes that differ only by
  266         // constant multiples at each bit position have a bounded
  267         // number of collisions (approximately 8 at default load factor).
  268         h ^= (h >>> 20) ^ (h >>> 12);
  269         return h ^ (h >>> 7) ^ (h >>> 4);
  270     }
  271 

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

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