请考虑以下代码:
HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)
hs.size()
将给出 1 因为HashSet
不允许重复,因此只会存储一个元素。
我想知道我们是否添加了重复元素,然后它会替换前一个元素还是根本不添加它?
另外,同样的情况会发生什么HashMap
?
请考虑以下代码:
HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)
hs.size()
将给出 1 因为HashSet
不允许重复,因此只会存储一个元素。
我想知道我们是否添加了重复元素,然后它会替换前一个元素还是根本不添加它?
另外,同样的情况会发生什么HashMap
?
您需要知道的第一件事是它的HashSet
行为类似于 a Set
,这意味着您将对象直接添加到HashSet
并且它不能包含重复项。您只需将您的价值直接添加到HashSet
.
但是,HashMap
是一种Map
类型。这意味着每次添加条目时,都会添加一个键值对。
HashMap
你可以有重复的值,但不能有重复的键。在HashMap
新条目中将替换旧条目。最近的条目将在HashMap
.
理解 HashMap 和 HashSet 之间的联系:
记住,HashMap
不能有重复的键。幕后HashSet
使用HashMap
.
当您尝试将任何对象添加到 中HashSet
时,此条目实际上作为键存储在中HashMap
- 与HashMap
在幕后使用的相同HashSet
。由于这个底层HashMap
需要一个键值对,因此为我们生成了一个虚拟值。
现在,当您尝试将另一个重复的对象插入同一个对象时HashSet
,它会再次尝试将其作为键插入到HashMap
下面。但是,HashMap
不支持重复。因此,HashSet
仍然会导致只有一个该类型的值。附带说明一下,对于每个重复的键,由于为我们在 HashSet 中的条目生成的值是一些随机/虚拟值,因此根本不会替换键。它将被忽略,因为删除密钥并添加回相同的密钥(虚拟值相同)根本没有任何意义。
概括:
HashMap
允许重复values
,但不允许keys
。
HashSet
不能包含重复项。
玩对象的添加是否成功完成,你可以检查boolean
调用时返回的值.add()
,看看它是否返回true
或false
。如果它返回true
,它被插入。
文档对此非常清楚:HashSet.add
不取代:
如果指定的元素尚不存在,则将其添加到此集合中。更正式地说,如果此集合不包含元素 e2,则将指定的元素 e 添加到此集合中,使得 (e==null ? e2==null : e.equals(e2))。如果该集合已包含该元素,则调用将保持该集合不变并返回 false。
但将替换:HashMap.put
如果映射先前包含键的映射,则替换旧值。
在 HashSet 的情况下,它不会取代它。
从文档:
http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add(E )
“如果指定的元素不存在,则将其添加到此集合中。更正式地说,如果此集合不包含元素 e2,则将指定的元素 e 添加到此集合中,这样 (e==null ? e2==null : e.equals( e2))。如果该集合已经包含该元素,则调用保持该集合不变并返回 false。
如果我错了,请纠正我,但你得到的是字符串,“Hi”==“Hi”并不总是正确的(因为它们不一定是同一个对象)。
您得到 1 答案的原因是 JVM 将在可能的情况下重用字符串对象。在这种情况下,JVM 正在重用字符串对象,从而覆盖 Hashmap/Hashset 中的项目。
但是您不能保证这种行为(因为它可能是具有相同值“Hi”的不同字符串对象)。您看到的行为仅仅是因为 JVM 的优化。
HashMap
基本上包含Entry
随后包含Key(Object)
和Value(Object)
.InternallyHashSet
并且确实替换了一些您已经指出的值..但它真的替换了键吗???不..这就是这里的技巧HashMap
。将其值保留为底层中的键,值只是一个虚拟对象。因此,如果您尝试在 HashMap 中重新插入相同的值(底层映射中的键)。它只是替换虚拟值而不是键(HashSet 的值)。HashMap
HashMap
HashMap
看下面的 HashSet 类代码:
public boolean [More ...] add(E e) {
return map.put(e, PRESENT)==null;
}
这里 e 是 HashSet 的值,但底层 map.and 的键永远不会被替换。希望我能够消除混乱。
您需要先检查 Hash map 中的 put 方法,因为 HashSet 由 HashMap 备份
换一种说法:当您将键值对插入到键已经存在的 HashMap 中时(从某种意义上说,hashvalue() 给出了相同的值,而 equal() 为真,但是这两个对象仍然可以在几个方面有所不同),键不会被替换,但值会被覆盖。键仅用于获取 hashvalue() 并使用它在表中查找值。由于 HashSet 使用 HashMap 的键并设置(对用户而言)并不重要的任意值,因此 Set 的元素也不会被替换。