Java HashMap实现hashcode问题

Java HashMap实现hashcode问题,java,hashmap,Java,Hashmap,在这里查看Java HashMap的实现:我注意到以下几点: 使用的内部数据结构是一个数组,它在每个索引处存储对链表中第一个条目的引用。数组索引基于键的hashcode,链表表示该特定hashcode的bucket。 我发现有趣的是indexFor(inth,intlength)方法,对于给定的键,它决定数组中要查找的bucket。但是这个实现,returnh&(length-1)看起来很奇怪,因为对于与给定数组索引不一致的不确定数量的hashcode,该方法将返回0。因此,无论您为对象实现了什

在这里查看Java HashMap的实现:我注意到以下几点:

使用的内部数据结构是一个数组,它在每个索引处存储对链表中第一个条目的引用。数组索引基于键的hashcode,链表表示该特定hashcode的bucket。 我发现有趣的是indexFor(inth,intlength)方法,对于给定的键,它决定数组中要查找的bucket。但是这个实现,returnh&(length-1)看起来很奇怪,因为对于与给定数组索引不一致的不确定数量的hashcode,该方法将返回0。因此,无论您为对象实现了什么独特的hashcode,数组中的0 bucket都很可能充满了对象,因此您不会受益于独特的hashcode应该为您提供的功能,即更快的数据访问

我错过什么了吗


克里斯蒂安我不太明白你认为问题出在哪里


h&(长度-1)
是计算
h%n
的简单方法,其中
n
是二的幂。据我所知,没有任何理由说明
h%n
应该给出一个不自然的大量零。

我不太理解您认为的问题是什么


h&(长度-1)
是计算
h%n
的简单方法,其中
n
是二的幂。据我所知,
h%n
没有任何理由会给出不自然的大量零。

HashMap源代码中缺少以下Javadoc:

/**
 * The table, resized as necessary. Length MUST Always be a power of two.
 */
transient Entry<K,V>[] table;
/**
*表,根据需要调整大小。长度必须始终是2的幂。
*/
瞬态条目[]表;

这意味着
table.length-1将始终是一个1序列。

HashMap源代码中缺少以下Javadoc:

/**
 * The table, resized as necessary. Length MUST Always be a power of two.
 */
transient Entry<K,V>[] table;
/**
*表,根据需要调整大小。长度必须始终是2的幂。
*/
瞬态条目[]表;

这意味着
table.length-1
将始终是1的序列。

这次我有另一个与hashtable类相关的问题。在此实现中,数组中的bucket索引是使用key.hashcode%array.length计算的。这里array.length不是2的幂。假设我们有一个长度为11的初始数组,首先插入一个hashcode=1的键,数组索引为1,然后插入另一个hashcode=12的键,数组索引也为1。这是否意味着具有不同hashcode的两个键的对象将存储在同一个bucket中?正确,但如果您指定了一个良好的初始值(即15),则调整大小公式
oldCapacity*2+1
将保持良好状态。在这些情况下,素数是一个典型的建议,它会运行得相当好。如果您指定了糟糕的初始大小,它将随着大小调整而变得更好。归根结底,它并不是完美的——任何数据结构都不是完美的。如果您非常关心效率-我建议您检查:-它为您提供了足够的绳子来做任何您想做的事情:-)这次我有另一个与hashtable类相关的问题。在此实现中,数组中的bucket索引是使用key.hashcode%array.length计算的。这里array.length不是2的幂。假设我们有一个长度为11的初始数组,首先插入一个hashcode=1的键,数组索引为1,然后插入另一个hashcode=12的键,数组索引也为1。这是否意味着具有不同hashcode的两个键的对象将存储在同一个bucket中?正确,但如果您指定了一个良好的初始值(即15),则调整大小公式
oldCapacity*2+1
将保持良好状态。在这些情况下,素数是一个典型的建议,它会运行得相当好。如果您指定了糟糕的初始大小,它将随着大小调整而变得更好。归根结底,它并不是完美的——任何数据结构都不是完美的。如果你那么在意效率,我建议你检查一下:-它给你足够的绳子去做你想做的事情:-)