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

如何正确使用hashcode方法?

吴伟志
2023-03-14

我正在准备Java认证,显然我不能正确回答这个答案。

给定:

2. class Chilis {
3.     Chilis(String c, int h) { color = c; hotness = h; }
4.     String color;
5.     private int hotness;
6.     public boolean equals(Object o) {
7.         Chilis c = (Chilis)o;
8.         if(color.equals(c.color) && (hotness == c.hotness)) return true;
9.         return false;
10.     }
11.   // insert code here
12. }

它在第11行独立插入,为Chilis实现equals()和hashCode()契约?(选择所有适用内容。)

  • A。public int hashCode(){return 7;}
  • B。public int hashCode(){return hotness;}
  • C。public int hashCode(){return color.length();}
  • D。public int hashCode(){return(int)(Math.random()*200);}
  • E。public int hashCode(){return(color.length()+hotness);}

书中说:

A, B, C, and E are correct. They all guarantee that two objects that equals() says are
equal, will return the same integer from hashCode(). The fact that hotness is private
has no bearing on the legality or effectiveness of the hashCode() method.

现在我的A和B是对的,但C和E不对,因为我听起来不对。看下面的例子:

Under c = new Under("ciao", 9);
Map<Under, String> map = new HashMap<Under, String>();

map.put(c, "ciao");
System.out.println(map.get(c));
c.color = "uauauauauau";

System.out.println(map.get(c));

输出将是:

ciao
null

我说的是基于颜色的访问修饰符。在Object类的文档中,我们有契约:

  • 只要在执行Java应用程序的过程中对同一对象多次调用hashCode方法,只要在对象上进行equals比较时使用的信息未被修改,hashCode方法就必须始终如一地返回相同的整数。从应用程序的一次执行到同一应用程序的另一次执行,此整数不需要保持一致。
  • 如果根据equals(Object)方法,两个对象相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。
  • 如果根据equals(java.lang.Object)方法,两个对象不相等,那么对两个对象中的每一个调用hashCode方法就必须产生不同的整数结果,这并不是一个要求。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

那么根据这些规则的第一条,是否应该预期会有这种行为呢?

共有2个答案

井唯
2023-03-14

通常,hashCode在对象生存期内不应该更改,因此它应该使用final字段。由于颜色可以在执行过程中更改,所以不应该在hashcode或equals中使用

仲孙默
2023-03-14

从您引用的文档中可以看到:

在执行Java应用程序的过程中,只要在同一对象上多次调用hashCode方法,它就必须一致地返回相同的整数,前提是在对象上进行equals比较时使用的信息没有被修改。从应用程序的一次执行到同一应用程序的另一次执行,这个整数不需要保持一致。

所以这是预期的行为。如果equalshashcode使用可变字段,并且您将受影响的对象放在一个HashMap中,并且值发生了变化,那么所有的赌注都结束了。

 类似资料:
  • 我是Spring的新手。在@Bean方法中注入Bean的这两种方法有什么区别?我应该使用哪个,为什么? 而且

  • 本文向大家介绍浅谈Java中hashCode的正确求值方法,包括了浅谈Java中hashCode的正确求值方法的使用技巧和注意事项,需要的朋友参考一下 本文研究的主要是Java中hashCode的正确求值方法的相关内容,具体如下。 散列表有一项优化,可以将对象的散列码(hashCode)缓存起来,如果散列码不匹配,就不会检查对象的等同性而直接认为成不同的对象。如果散列码(hashCode)相等,才

  • 问题内容: 我只想检索UserAccount类中的某些列,所以我有以下代码: 我得到了空值作为回报。但是,如果我注释掉setProjections,我将获得具有所有属性的用户。在这种情况下,如何正确使用setProjection? 问题答案: 它返回一个Object数组,因此代码应为:

  • 问题内容: 我不知道我在哪里错了:/。当我运行这段代码时,我得到的只是一个空白元素。我似乎无法让insertRule方法执行任何操作(甚至不会产生错误)。我想念什么吗? 问题答案: 这有点令人困惑,但是您的代码确实可以工作,只是您看不到返回的XML树中插入的规则。 为了验证您的代码是否有效,您可以执行两个测试: 运行上面的代码片段,您可以看到CSS规则确实适用。并且属性也在控制台中更改。 当浏览器

  • 问题内容: 如何使用从类路径中查找递归资源? 例如 在“目录”中查找所有资源:想象一下 不幸的是,这只会检索到恰好该“目录”。 所有资源都已命名(递归) 但这返回一个空。 还有一个额外的问题:与有什么不同? 问题答案: 没有办法递归搜索类路径。您需要知道资源的完整路径名才能以这种方式检索它。该资源可能位于文件系统中的目录中,也可能位于jar文件中,因此它不像执行“类路径”的目录列表那样简单。您将需

  • 问题内容: 我最近开始使用ScriptManager。我有一个通过JavaScript填充的ASP.NET DropDownList控件。但是,我正在使用事件验证。因此,如果我不使用下拉菜单中的“ RegisterForEventValidation”调用,则会遇到以下错误。我怎么知道在第二个参数中设置什么值(我有“值”)?我正在通过JavaScript填充下拉列表,因此我不知道后面的代码中包含哪