哈希码和等于

equalshashCode方法必须一致,这意味着当两个对象根据equals方法相等时,它们的hashCode方法应返回相同的哈希值。

如果我们不重写hashCode()方法,Java将返回唯一的哈希码。

 class HashValue { int x; public boolean equals(Object oo) { // if(oo instanceof Hashvalue) uncommenting ths gives error.dunno why? // :| HashValue hh = (HashValue) oo; if (this.x == hh.x) return true; else return false; } HashValue() { x = 11; } } class Hashing { public static void main(String args[]) { HashValue hv = new HashValue(); HashValue hv2 = new HashValue(); System.out.println(hv.hashCode()); System.out.println(hv2.hashCode()); if (hv.equals(hv2)) System.out.println("EQUAL"); else System.out.println("NOT EQUAL"); } } 

为什么取消注释该行会产生编译错误?

如果对象具有不相等的哈希码,为什么即使默认哈希码变化,它们也显示相等?

平等仅由方法equals()决定。 方法hashCode()用于其他情况,例如Map或Set。 在实际调用equals(效率)之前,它有点像先决条件或提示。 因此假设如果2个对象相等(即equals()返回true),则它们的hashCodes()必须返回相同的值。

所以在你的代码中,2个对象是相等的,只要你的overriden equals()返回true,无论hashCode()做什么。 在比较相等性时,根本不调用hashCode()。

这个问题有关于equals()和hashCode()之间关系的更深入的信息。

首先,在该行中,您需要将Hashvalue更改为HashValue ,因为您的类实际上称为HashValue

然后,取消注释该行为您提供:

 public boolean equals(Object oo) { if(oo instanceof HashValue) HashValue hh = (HashValue)oo; if (this.x==hh.x) { return true; } else { return false; } } 

这有一些问题:

  1. 这不能编译,因为当你最终使用它时, hh不在范围内。

  2. 第一个if语句要么在比较两个不是HashValues的东西(即抛出exception)时要么确保函数根本不运行,要么它应该返回false因为HashValues永远不会等于其他类型的对象。 我通常更喜欢返回false来抛出exception。

  3. 第二个if语句是多余的,因为您只是返回条件评估的内容。

像这样重做你的方法:

 public boolean equals(Object oo) { if(!(oo instanceof Hashvalue)) { return false; } HashValue hh = (HashValue)oo; return (this.x == hh.x); } 

这也不太对劲。 为了确保所有相等的对象具有相同的哈希码,您必须在HashValue覆盖hashCode() ,并且必须确保它符合保证。 在这里,你可以添加这个:

 // inside HashValue int hashCode() { return x; } 

实现很简单,因为你的对象只是一个int的包装器。 随着对象越来越复杂,你需要更加努力地思考。

对于初学者,你需要在“Hashvalue”中大写v

 if(oo instanceof Hashvalue) 

应该

 if (oo instanceof HashValue) 

HashValueHashvalue是两个不同的标识符

if(oo instanceof HashValue)有效的,因为你的类名是HashValue而不是Hashvalue

编辑:

您的代码不起作用,因为当您使用它时, hh不在范围内。

这有效:

 /* A program to check hashcode values for object @Author Myth17 */ class HashValue { int x; public boolean equals(Object oo) { HashValue hh=new HashValue(); if(oo instanceof HashValue) hh = (HashValue)oo; if(this.x==hh.x) return true; else return false; } HashValue() { x=11; } } class Hashing { public static void main(String args[]) { HashValue hv=new HashValue(); HashValue hv2=new HashValue(); System.out.println(hv.hashCode()); System.out.println(hv2.hashCode()); if(hv.equals(hv2)) System.out.println("EQUAL"); else System.out.println("NOT EQUAL"); } } 

正如其他人已经指出的那样,方法“等于”而“hashCode”用于不同的目的。

Object中的hashCode方法的规范可以推断出:

  • 当对它们调用hashCode方法时, 需要两个相等的对象返回相同的整数结果
  • 强烈建议不等对象返回不同的整数值

您的代码(考虑到tgamblin提出的更改)满足条件(a),因此您将输出视为“EQUALS”。

但是遵循(b)是一种很好的做法,因为当类的实例用作哈希表键时,这会带来更好的性能。 当不相等的对象返回相同的hashCode并且如果将这样的类用作散列表键时,则每个对象散列到同一个桶,并且散列表将退化为链接列表,从而导致性能降低。

在以下代码中:

 public boolean equals(Object oo) { if(oo instanceof Hashvalue) HashValue hh = (HashValue) oo; if (this.x == hh.x) return true; else return false; } 

有几个问题:1。编译器无法识别Hashvalue。 它应该是“HashValue”2。一旦超出if-block,hh就超出了范围。 因此,编译器错误。

您可以将程序更改为以下程序,它将起作用:

  public boolean equals(Object oo) { if(!(oo instanceof Hashvalue)) return false; HashValue hh = (HashValue) oo; if (this.x == hh.x) return true; else return false; } 

或者你可以使它更简洁如下:

  public boolean equals(Object oo) { if(oo instanceof Hashvalue && this.x == ((HashValue) oo).x) return true; return false; } 
 int x; public static void main(String args[]){ E a = new E(); System.out.println(a.hashcode()); E b = new E(); System.out.println(b.hashcode()); } public int hashcode(){ return x*17; }