向 HashSet/HashMap 中添加重复值是否替换以前的值

请考虑以下代码:

HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)

hs.size()将给出1,因为 HashSet不允许重复,所以只存储一个元素。

我想知道,如果我们添加了重复的元素,那么它是替换了前面的元素,还是根本没有添加它?

还有,在同样的情况下使用 HashMap会发生什么?

240848 次浏览

对于 HashMap,它用新值替换旧值。

HashSet的情况下,没有插入该项。

医生在这一点上非常清楚: HashSet.add 没有代替:

如果指定的元素尚未存在,则将该元素添加到此集中。更正式地说,如果这个集合不包含元素 e2,那么将指定的元素 e 添加到这个集合中(e = = null?E2 = = null: e.equals (e2)).如果该集合已经包含元素,则调用保持该集合不变并返回 false。

HashMap.put代替 威尔:

如果映射以前包含键的映射,则替换旧值。

它的情况下,哈希集,它不会取代它。

来自文件:

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 的优化。

您需要知道的第一件事是,HashSet的行为类似于 Set,这意味着您将对象直接添加到 HashSet,而且它不能包含重复的对象。您只需在 HashSet中直接添加您的值。

但是,HashMapMap类型。这意味着每次添加一个条目时,都要添加一个键-值对。

HashMap中可以有重复的值,但不能有重复的键。在 HashMap中,新的条目将取代旧的条目。最近的入口将在 HashMap

理解 HashMap 和 HashSet 之间的链接:

请记住,HashMap不能有重复的键。幕后 HashSet使用 HashMap

当您试图将任何对象添加到 HashSet中时,这个条目实际上存储为 HashMap中的一个键-与 HashSet幕后使用的 HashMap相同。因为这个底层的 HashMap需要一个键-值对,所以会为我们生成一个虚拟值。

现在,当您尝试将另一个重复对象插入到同一个 HashSet中时,它将再次尝试将其作为位于下面的 HashMap中的键插入。但是,HashMap不支持重复。因此,HashSet仍将导致只有该类型的一个值。另外,对于每个重复的键,由于在 HashSet 中为条目生成的值是一些随机/虚拟值,因此根本不会替换键。它将被忽略,因为删除键并添加回相同的键(虚拟值是相同的)将没有任何意义。

摘要:

HashMap允许复制 values,但不允许复制 keysHashSet不能包含重复内容。

要处理添加对象是否成功完成,可以检查调用 .add()时返回的 boolean值,并查看它是否返回 truefalse。如果它返回 true,它就被插入。

您需要首先检查 HashMap 中的 put 方法,因为 HashSet 是由 HashMap 备份的

  1. 当您将重复值添加到 HashSet 中时,
  2. 一个条目(“ one”,PREENT)将被插入到 Hashmap (针对所有 值添加到集合中,该值将是“ PREENT”,如果类型为 Object)
  3. Hashmap 将条目添加到 Map 中并返回值,这就是本例中的情况 如果条目不存在,则为“ PRESENT”或 null。
  4. 如果从 Hashmap 返回的值相等,Hashset 的 add 方法将返回 true 否则为 null 否则为 false 这意味着一个条目已经存在..。

换一种说法: 当你把一个键-值对插入到一个键已经存在的 HashMap (从某种意义上说,hashvalue ()给出了相同的值,但是这两个对象仍然可以在几个方面有所不同) ,键没有被替换,但是值被覆盖了。键只是用来获取 hashvalue ()并在表中找到它的值。 由于 HashSet 使用 HashMap 的键并设置任意的值(对用户而言) ,因此也不会替换 Set 的 Element。

HashMap基本上包含 Entry,后来又包含 Key(Object)Value(Object)。内部 HashSetHashMapHashMap确实替换了一些你们已经指出的值。.但它真的能代替钥匙吗?没有。.这就是关键所在。HashMap将其值作为基础 HashMap中的键,而 Value 只是一个虚拟对象。它只替换虚拟值,而不替换 Key (Value for HashSet)。

查看下面的 HashSet 类代码:

public boolean  [More ...] add(E e) {


return map.put(e, PRESENT)==null;
}

这里 e 是 HashSet 的值,但是基础 map.and key 永远不会被替换。希望我能解释清楚。

考虑这个问题的简单方法是,如果您查看散列的 add 方法,您将看到一个可选的布尔 T/F 返回类型。只有在散列集不能添加元素时,作为 false 的返回类型才有意义。