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

Java 为什么put的HashMap和Hastable方法有区别?,java,hashmap,hashtable,Java,Hashmap,Hashtable,我想知道put方法在HashMap和Hashtable HashTableput方法代码 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 == has

我想知道
put
方法在
HashMap
Hashtable

HashTable
put方法代码

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;
         }
     }
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;
         }
     }
为什么哈希表有不同的查找索引的代码

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

而hashMap有jdk设计器提供的
hash()
函数。

什么是二进制的
0x7FFFFFFF
?这是
011111111111111111111

请注意,最左边的位是
0
。这意味着该数字始终为正(因为最左边的位为零)。由于
&
,使用此二进制文件生成的每个数字都将是非负数,因为:

在此之后,使用
%
操作符确保我们在
tab.length
的范围内

您没有发布
HashMap
如何生成索引的实现。我觉得没什么不同。毕竟,他们的逻辑非常相似

HashMap
为正在执行的操作调用
indexFor:
返回h&(长度-1)

重要提示:
HashTable
HashMap
旧,难怪有不同的实现。

HashTable:

int index = (hash & 0x7FFFFFFF) % tab.length;
这意味着: 哈希-不带表长度的最左边位(符号)模

哈希映射:

int i = indexFor(hash, table.length);
正在呼叫:

static int indexFor(int h, int length) {
   return h & (length-1);
}
这意味着模长为1 这两者差别不大,实际上,
模长度-1
意味着我们能得到的最大值是长度-2。在这里,长度-1确保我们不会遇到我们将得到
0xFFFFFFFF
的场景,实际上我们可能得到的最高值将是
0xfffffe

不同之处在于低位(在HashMap中,与在HashTable中的高位相比)。现在我们应该问(递归地)为什么会这样。答案隐藏在hash()方法中,该方法出现在代码的第一行(上面),它也不同于HashTable实现:

int hash = hash(key.hashCode());
解释见:


hashMap的hash()函数所做的相同操作都是通过调用
hashCode
来获取哈希值的。区别在于调用
indexFor
方法。你知道这个方法的作用吗?这不仅仅是在执行问题中的路线吗?因为有
Hashtable
是1995年左右写的,HashMap
是1997年左右写的,不是完全由同一个人写的。您必须要求作者获取意见以外的任何信息。但无论如何,他们提供了更新,所以他们不能修改哈希表的类吗?当然可以。你到底为什么认为他们应该这样做?
int hash = hash(key.hashCode());
           /**
  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