我正在看HashMap
在Java中的实现,在某一点上卡住了。
如何计算indexFor
函数?
static int indexFor(int h, int length) {
return h & (length-1);
}
谢谢
匿名用户
上面的答案很好,但我想进一步解释为什么Java可以使用indexFor
来创建索引
例如,我有一个类似这样的HashMap
(这个测试是在Java7上进行的,我看到Java8对HashMap做了很多更改,但我认为这个逻辑仍然非常好)
// Default length of "budget" (table.length) after create is 16 (HashMap#DEFAULT_INITIAL_CAPACITY)
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("A",1); // hash("A")=69, indexFor(hash,table.length)=69&(16-1) = 5
hashMap.put("B",2); // hash("B")=70, indexFor(hash,table.length)=70&(16-1) = 6
hashMap.put("P",3); // hash("P")=85, indexFor(hash,table.length)=85&(16-1) = 5
hashMap.put("A",4); // hash("A")=69, indexFor(hash,table.length)=69&(16-1) = 5
hashMap.put("r", 4);// hash("r")=117, indexFor(hash,table.length)=117&(16-1) = 5
您可以看到带有键“A”
的条目索引和带有键“P”
的对象以及带有键“r”
的对象具有相同的索引(=5)。下面是我执行上面代码后的调试结果
图中的表格在这里
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {
transient HashMap.Entry<K, V>[] table;
...
}
=
static class Entry<K, V> implements java.util.Map.Entry<K, V> {
...
HashMap.Entry<K, V> next;
}
您可以通过阅读HashMap
中的代码来再次验证它。
与现在一样,您可以认为HashMap
永远不需要更改大小(16),因为indexFor()
总是返回值
if (this.size >= this.threshold ...) {
this.resize(2 * this.table.length);
HashMap
将在size
什么是threadhold
<代码>Thread固定计算如下
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final float DEFAULT_LOAD_FACTOR = 0.75F;
...
this.threshold = (int)Math.min((float)capacity * this.loadFactor, 1.07374182E9F); // if capacity(table.length) = 16 => threadhold = 12
尺寸是多少<代码>大小计算如下
当然,size
这里不是表格。长度
当您将新条目放入HashMap
和HashMap
时,需要创建新条目(请注意,HashMap
键相同时不创建新条目,它只会覆盖现有条目的新值),然后size
void createEntry(int hash, K key, V value, int bucketIndex) {
...
++this.size;
}
希望能有所帮助
它不是在计算散列,而是在计算桶。
表达式h
散列本身由您试图存储的对象的hashCode()
方法计算。
您在这里看到的是根据哈希h
计算存储对象的“桶”。理想情况下,为了避免冲突,您将拥有与h
最大可实现值相同数量的桶——但这可能太需要内存了。因此,您通常拥有较少数量的桶,有冲突的危险。
如果h
是1000,但是您的底层数组中只有512个桶,您需要知道将对象放在哪里。通常,对h
进行mod
操作就足够了,但是这太慢了。考虑到HashMap
的内部属性,底层数组的桶数总是等于2^n
,Sun的工程师可以使用h的想法
例:
hash h: 11 1110 1000 -- (1000 in decimal)
length l: 10 0000 0000 -- ( 512 in decimal)
(l-1): 01 1111 1111 -- ( 511 in decimal - it will always be all ONEs)
h AND (l-1): 01 1110 1000 -- ( 488 in decimal which is a result of 1000 mod 512)
问题内容: 我正在研究Java 的实现,只停留在一点。 该函数如何计算? 谢谢 问题答案: 它不是在计算 哈希 ,而是在计算 存储桶 。 表达确实逐位上使用,这是像一个位掩码,以便仅返回的低位比特,从而使得对于一个超高速变体。
问题内容: 在一次采访中,我被要求计算内存使用量,如果其中有200万个项目,则估计将消耗多少内存。 例如: 映射是这样的。 我如何估计Java中此HashMap对象的内存使用情况? 问题答案: 简短的答案 为了找出对象的大小,我将使用探查器。例如,在YourKit中,您可以搜索对象,然后获取它以计算其深度大小。这将使您很清楚地知道如果对象是独立的,则使用多少内存,并且该对象的大小是保守的。 怪癖
问题内容: 说我有阵列 数组的长度为20,但计数为0。如何获取计数? 问题答案: “计数”是什么意思?具有非零值的元素数量?您只需要数一下。 有 没有区别 数组和一个已之间 明确地 设置与零个值。例如,这些数组是无法区分的: Java中的数组始终具有固定大小-可通过字段访问。没有“当前使用的阵列数量”的概念。
本文向大家介绍java实现水仙花数的计算,包括了java实现水仙花数的计算的使用技巧和注意事项,需要的朋友参考一下 看到标题java实现水仙花数,首先先要知道什么是水仙花数,具体了解一下 所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数 列如153=1*1*1+5*5*5+3*3*3 那么153就是水仙花数,首先是分析需要的功能,首先他是一个3位数。 那值一定在100-1000之间,必定
问题内容: 我有一个Java客户端正在调用Web服务操作,该操作将证书“ thumbprint”作为参数。我相信指纹是证书的公钥的某种SHA16哈希,采用十六进制字符串格式,但是我不确定。 .NET框架似乎包括一种获取此值的简单方法(X509Certificate2.Thumbprint属性)。在Windows中查看.cer文件的属性也会显示指纹,如下所示: 因此,我的问题是:如果我有java.s
我正在努力为下面给出的学生类编写合适的hashCode函数。 1)我认为hashCode应该足够好,这样两个不同对象的hashCode就不会相互冲突。 观察:对于这个实现,当我调试并检查“HashMap的内部表对象”类时,我发现HashMap中的每个条目都分配了不同的bucket位置。 问题:在每个索引处有一个桶(列表/树)的目的是什么。 实施: 2)如果我允许hashCode冲突: 观察:对于这