当前位置: 首页 > 知识库问答 >
问题:

HashSet是如何与hashCode()相关的?

冀崇凛
2023-03-14

我试图更深入地理解java.util.Collection和java.util.Map,但我对HashSet的功能有些怀疑:

所以,我的问题是:如果一个HashSet总是有一个Hashtable在后台工作,那么每次我们使用HashSet.add()方法向HashSet添加一个新元素时,HashSet都应该将它添加到它的内部Hashtable中。但是,哈希表要求一个值和一个键,那么它使用什么键呢?它是否只是使用我们试图添加的值作为键,然后使用它的hashcode?如果我对HashSet实现说错了,请指正。

我有的另一个问题是:一般来说,什么类可以使用java对象的hashCode()方法?我之所以这么问,是因为在文档中,它说每次重写equals()方法时,我们都需要重写hashCode()方法。好的,这确实是有意义的,但我怀疑的是,这是否只是我们应该做的一个建议,以保持每件事都“漂亮和完美”(以这种方式),或者是否真的有必要,因为可能很多Java默认值类会不断地使用对象的hashCode()方法。在我的视野中,我看不到其他类使用这种方法,而不是那些与集合相关的类。非常感谢你们,伙计们

共有1个答案

庞元青
2023-03-14

如果查看HashSet的实际javacode,就可以看到它的作用:

 // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
...

 public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

所以您要添加的元素是backing hashmap中的键,并以一个虚拟值作为值。hashset从未实际使用过这个伪值。

关于重写equals和hashcode的第二个问题:

因此,如果重写equals()但不重写hashcode(),就可能发生这种情况

object1.equals(object2) //true

MySet.add(object1);

MySet.contains(object2); //false but should be true if we overrode hashcode()

因为contains将使用hashcode查找要在其中搜索的bucket,所以我们可能会返回一个不同的bucket,而不会找到相同的对象。

 类似资料:
  • 我试图覆盖提到的方法为我的: MyObject: 如何重写hashcode(),equals()和compareTo()方法? 目前我有以下几点: 我读到通过id比较是不够的,这是对象是数据库的持久实体(见这里)。 此类型的所有对象的名称和编号不是唯一的。 那么我应该如何覆盖它呢? 我还需要比较它里面的hashMap吗? 我很困惑。该对象唯一独特的地方是map myMap,它将在生命周期的后期填充

  • 您好,当我想在不更改hashCode()方法的情况下拥有一个自定义HashSet时,有人可以为我指出正确的方向。用法是拥有一组必须具有不同的一个(或多个)属性的对象。 例如,对于这个类: 我希望有UserNameSet,它只允许包含具有不同名称的用户。我不想覆盖User中的hashCode和equals方法,因为我仍然想区分同名但不同电子邮件的用户。 我想为这一个HashMap重写hashCode

  • 我知道SOAP REST比较称REST是更好的选择,然后有一些工业广告称OPC UA比REST更好… Pro REST: https://spf13.com/post/soap-vs-rest/ Pro OPC ua: https://www.maintworld.com/partner-articles/why-use-opc-ua-instrast-of-a-restful-interface

  • 问题内容: 因此,我有一个自定义班级班级,该班级将有一组其他自定义班级的学生。因此它将看起来像这样: 现在,我将向集合中的学生添加和删除许多学生,并且还将改变已经在集合中的学生的许多私有字段。 问题:应该使用哪种数据结构来最好地实现此目的?由于我将更改set Student中Student对象的属性(从而更改哈希码),因此我应该改用ArrayList吗? 问题答案: 我应该使用哪种数据结构来最好地

  • 问题内容: 它们之间有什么区别?我知道 LinkedHashSet是HashSet的有序版本,可在所有元素上维护双链列表。当您关心迭代顺序时,请使用此类而不是HashSet。当您遍历HashSet时,顺序是不可预测的,而LinkedHashSet可让您按插入元素的顺序来遍历元素。 但是在LinkedHashSet的源代码中,只有HashSet的调用构造函数。那么双向链接的列表和插入顺序在哪里? 问

  • 问题内容: 当覆盖java.lang.Object的equals()函数时,javadocs建议, 通常,无论何时重写此方法,都必须重写hashCode方法,以维护hashCode方法的常规约定,该约定规定相等的对象必须具有相等的哈希码。 hashCode()方法必须为每个对象返回一个 唯一的整数 (当根据内存位置比较对象时,这很容易做到,只需返回对象的 唯一的整数 地址即可) 应该如何重写has