我有一个HashMap,我用它来存储 SplitCriteria 类型的对象,使用String作为键
Map<String, SplitCriteria> criteriaMap = new HashMap<String, SplitCriteria>();
示例SplitCriteria对象包含以下内容:
SplitCriteria [
id=4,
criteriaName="Location",
criteriaAbrevName="Loc",
fieldName="LOCATION",
isMandatory=false
]
id 为长, isMandatory 为布尔值,其余为字符串。
我循环遍历以前填充的相同对象类型的数组,总计数 7 ,使用fieldName属性作为键将每个数据添加到HashMap:
for(SplitCriteria split : selectedCriteria){
String fieldName = split.getFieldName();
criteriaMap.put(fieldName, split);
}
此循环完成后,地图的大小似乎 7 ,但查看表格内容时,只有 6 对象存在。
通过研究这个问题,我逐渐明白,如果与键发生冲突,则使用地图中条目的next
属性将冲突对象“链接”在一起。
从下图中,您可以看到这是我的场景中发生的事情,但这两个键完全不同!
我也在put方法的文档中读到了这个
如果地图以前包含该键的映射,则旧值将替换为指定值
和
返回: 与key关联的上一个值,如果没有key的映射,则返回null。
因此,如果密钥发生冲突,我希望返回旧条目,但事实并非如此。
我不知道这是怎么回事,因为我使用的每个键与下一个键完全不同。
非常感谢任何解决此问题的帮助。
水稻
修改 当我尝试在稍后阶段检索对象时,我得到一个空的响应
SplitCriteria criteria = (SplitCriteria) criteriaMap.get(key);
答案 0 :(得分:5)
但是查看表格内容只有6个对象
不,看看size
- 它的7.你在同一个桶里只得到两个值。它们不会被确切的哈希值冲突,但它们做会被桶冲撞。没关系。
当您使用地图时,您将无法观察到 - 如果您只是使用公共API,那么您将看到所有7个条目,但没有任何暗示。这就是为什么我一般建议使用调试器避免深入挖掘对象的内部细节,直到你真的确实确定存在问题为止。
答案 1 :(得分:4)
HashMap被组织成桶。
每个存储桶都有一个链接列表,其中包含该存储桶的条目。
在你的情况下,你有十六个桶(大小为table
),其中六个被填充(table
中的对象),你的七个条目在这六个列表中(这意味着其中一个有两个长度。)
如果你打开那些HashMap$Entry
个对象,你会发现一个指针指向&#34; next&#34;条目。
&#34; LOCATION&#34;和&#34; PAY_FREQUENCY&#34;碰巧在同一个桶里。
如果你继续将更多的条目推入地图,它最终会调整自己的大小以获得更多的存储桶(以避免遇到长列表的问题)。
答案 2 :(得分:2)
可以将两个不同的键分配给HashMap的同一个bin(Java 6实现中的相同数组条目)。在这种情况下,它们将被链接在一个链表中。但是,这两个键都不会覆盖另一个键,因为它们彼此不相等。
HashMap的大小为7,这意味着它包含7个键值对(即使其中2个存储在同一个bin中)。
答案 3 :(得分:1)
当两个不同的键产生相同的哈希值时发生冲突。散列值在HashMap中用于快速导航到元素。所以这意味着,当两个键冲突时,它们是不同的,但两者都产生相同的哈希值。用于计算哈希值的算法是HashMap的内部算法。 看一下这篇博文:http://javahungry.blogspot.com/2013/08/hashing-how-hash-map-works-in-java-or.html
答案 4 :(得分:0)
该表只有16
个条目。这意味着仅基于4
位将密钥分配给存储区,因此同一存储区中的两个条目根本不可能。当您添加更多条目时,该表将会增长。
您无需关心这些细节。你应该关心的是地图有7
个条目。
答案 5 :(得分:0)
由于两个键的哈希码相同,因此桶位置相同,并且在HashMap中会发生冲突,因为HashMap使用LinkedList来存储对象,所以此条目(Map.Entry的对象包含键和值)将存储在LinkedList中
HashMap使用Key Object的哈希码来查找存储桶位置并检索Value对象,然后有两个Value对象存储在同一个存储桶中。 HashMap在LinkedList节点中存储Key和Value。 找到存储区位置后,我们将调用keys.equals()方法来识别LinkedList中的正确节点,并在Java HashMap中返回该键的关联值对象