HashMap.put()覆盖不同键的现有项

时间:2015-10-08 13:11:46

标签: java eclipse string hashmap

我有一个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属性将冲突对象“链接”在一起。

从下图中,您可以看到这是我的场景中发生的事情,但这两个键完全不同!

enter image description here

我也在put方法的文档中读到了这个

  

如果地图以前包含该键的映射,则旧值将替换为指定值

  

返回:   与key关联的上一个值,如果没有key的映射,则返回null。

因此,如果密钥发生冲突,我希望返回旧条目,但事实并非如此。

我不知道这是怎么回事,因为我使用的每个键与下一个键完全不同。

非常感谢任何解决此问题的帮助。

水稻

修改 当我尝试在稍后阶段检索对象时,我得到一个空的响应

SplitCriteria criteria = (SplitCriteria) criteriaMap.get(key);

6 个答案:

答案 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中返回该键的关联值对象