2 回答

TA贡献1817条经验 获得超6个赞
为什么HashMap(JDK1.8)中的hash计算不需要像ConcurrentHashMap那样考虑负hashCode?
最终,在这种情况下也需要考虑散列为负(传播后)的HashMap情况。只是这发生在代码的后面。
例如,在getNode(Java 8) 中,您会发现:
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
因为tab.length是 2 的幂,所以tab.length - 1是一个合适的位掩码,用于减少hash到数组的下标。
您可以放心,在或 的每个实现中HashMap,ConcurrentHashMap都有一些代码可以将哈希码简化为适合用作下标的数字。它会在那里……某个地方。
但也...不要指望这些类的代码很容易阅读。所有集合类都经过多次重新设计/调整,在各种测试用例中获得最佳(平均)性能。

TA贡献1830条经验 获得超3个赞
实际上它处理负指数计算。乍一看并不明显,但在访问元素(键或值)时在某些地方进行了计算。
int index = (n - 1) & hash, 其中n是表的长度
它只是处理负索引。
AFAIK,HashMap总是使用尺寸为2(例如,功率阵列16,32,64等等)。
假设我们有256( 0x100) 的容量,即2^8。在减法 1 之后,我们得到256 - 1 = 255which is0x100 - 0x1 = 0xFF 减法产生了在0to之间获得正确的桶索引,length-1以及按位和散列所需的精确位掩码。
256 - 1 = 255
0x100 - 0x1 = 0xFF
260( 0x104)的散列与进行按位与运算0xFF以产生 的桶号4。
257( 0x101)的散列与进行按位与运算0xFF以产生 的桶号1。
添加回答
举报