[英]Hashcode and equals
equals
和hashCode
方法必须一致,这意味着当两个对象根据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");
}
}
为什么取消注释该行会产生编译错误?
如果对象具有不相等的哈希码,为什么即使默认哈希码变化,它们也显示相等?
首先,在该行中,您需要将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;
}
}
这有一些问题:
这不会编译,因为当你最终使用它时, hh
不在范围内。
第一个if语句应该确保在比较两个不是HashValues的东西(即抛出异常)时根本不运行该函数,或者它应该返回false
因为HashValues永远不会等于其他类型的对象。 我通常更喜欢返回false
来抛出异常。
第二个if语句是多余的,因为您只是返回条件评估的内容。
像这样重写你的方法:
public boolean equals(Object oo) {
if(!(oo instanceof Hashvalue)) {
return false;
}
HashValue hh = (HashValue)oo;
return (this.x == hh.x);
}
这也不太对劲。 为了确保所有相等的对象具有相同的哈希代码,你必须覆盖hashCode()
的HashValue
, 你必须确保它不辜负保证。 在这里,你可以添加这个:
// inside HashValue
int hashCode() {
return x;
}
实现很简单,因为你的对象只是一个int
的包装器。 随着对象越来越复杂,你需要更加思考。
平等仅由方法equals()决定。 方法hashCode()用于其他情况,例如Map或Set。 在实际调用equals(效率)之前,它有点像先决条件或提示。 因此假设如果2个对象相等(即equals()返回true),则它们的hashCodes()必须返回相同的值。
所以在你的代码中,2个对象是相等的,只要你的overriden equals()返回true,无论hashCode()是什么。 在比较相等性时,根本不调用hashCode()。
这个问题有关于equals()和hashCode()之间关系的更深入的信息。
对于初学者,你需要在“Hashvalue”中大写v
if(oo instanceof Hashvalue)
应该
if (oo instanceof HashValue)
HashValue和Hashvalue是两个不同的标识符
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”用于不同的目的。
one can infer that: 从的hashCode方法的规范可以推断出:
has proposed) satisfies criteria (a) hence you get the output as "EQUALS". 您的代码(考虑到提出的更改)满足标准(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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.