Java HashMap实现hashcode问题
在这里查看Java HashMap的实现:我注意到以下几点: 使用的内部数据结构是一个数组,它在每个索引处存储对链表中第一个条目的引用。数组索引基于键的hashcode,链表表示该特定hashcode的bucket。 我发现有趣的是indexFor(inth,intlength)方法,对于给定的键,它决定数组中要查找的bucket。但是这个实现,returnh&(length-1)看起来很奇怪,因为对于与给定数组索引不一致的不确定数量的hashcode,该方法将返回0。因此,无论您为对象实现了什么独特的hashcode,数组中的0 bucket都很可能充满了对象,因此您不会受益于独特的hashcode应该为您提供的功能,即更快的数据访问 我错过什么了吗Java HashMap实现hashcode问题,java,hashmap,Java,Hashmap,在这里查看Java HashMap的实现:我注意到以下几点: 使用的内部数据结构是一个数组,它在每个索引处存储对链表中第一个条目的引用。数组索引基于键的hashcode,链表表示该特定hashcode的bucket。 我发现有趣的是indexFor(inth,intlength)方法,对于给定的键,它决定数组中要查找的bucket。但是这个实现,returnh&(length-1)看起来很奇怪,因为对于与给定数组索引不一致的不确定数量的hashcode,该方法将返回0。因此,无论您为对象实现了什
克里斯蒂安我不太明白你认为问题出在哪里
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
将保持良好状态。在这些情况下,素数是一个典型的建议,它会运行得相当好。如果您指定了糟糕的初始大小,它将随着大小调整而变得更好。归根结底,它并不是完美的——任何数据结构都不是完美的。如果你那么在意效率,我建议你检查一下:-它给你足够的绳子去做你想做的事情:-)