Java:为方便起见,在equals()中使用hashCode()?

考虑以下测试用例,将equals中的hashCode()方法用作方便的快捷方式是一种不好的做法吗?

public class Test { public static void main(String[] args){ Test t1 = new Test(1, 2.0, 3, new Integer(4)); Test t2 = new Test(1, 2.0, 3, new Integer(4)); System.out.println(t1.hashCode() + "\r\n"+t2.hashCode()); System.out.println("t1.equals(t2) ? "+ t1.equals(t2)); } private int myInt; private double myDouble; private long myLong; private Integer myIntObj; public Test(int i, double d, long l, Integer intObj ){ this.myInt = i; this.myDouble = d; this.myLong = l; this.myIntObj = intObj; } @Override public boolean equals(Object other) { if(other == null) return false; if (getClass() != other.getClass()) return false; return this.hashCode() == ((Test)other).hashCode();//Convenient shortcut? } @Override public int hashCode() { int hash = 3; hash = 53 * hash + this.myInt; hash = 53 * hash + (int) (Double.doubleToLongBits(this.myDouble) ^ (Double.doubleToLongBits(this.myDouble) >>> 32)); hash = 53 * hash + (int) (this.myLong ^ (this.myLong >>> 32)); hash = 53 * hash + (this.myIntObj != null ? this.myIntObj.hashCode() : 0); return hash; } } 

主方法输出:

 1097562307 1097562307 t1.equals(t2) ? true 

通常,比较hashCode()而不是使用equals()并不安全。 当equals()返回false时,hashCode() 可以 根据hashCode()的约定返回相同的值。

很坏! HashCode相等并不意味着equals返回true。 合同是两个相等的对象必须具有相同的hashCode。 但它没有说明具有相同HashCode的两个对象必须相等。

正如所有其他答案所述,这是不好的做法。 但是 ,您可能希望在equals方法中引用哈希代码的一种情况是,您有一个不可变对象并且先前已缓存哈希代码 。 这允许您在执行完整比较之前执行廉价的不精确比较。 例如:

 public class MyImmutable { private final String a; private final String b; private final int c; private int hashCode; public MyImmutable(String a, String b, int c) { this.a = a; this.b = b; this.c = c; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MyImmutable that = (MyImmutable) o; // Compare cached hashCodes first before performing more expensive comparison. return hashCode == that.hashCode() && c == that.c && !(a != null ? !a.equals(that.a) : that.a != null) && !(b != null ? !b.equals(that.b) : that.b != null); } @Override public int hashCode() { if (hashCode == 0) { // hashCode not cached, or it was computed as 0 (we recalculate it in this case). hashCode = a != null ? a.hashCode() : 0; hashCode = 31 * hashCode + (b != null ? b.hashCode() : 0); hashCode = 31 * hashCode + c; } return hashCode; } } 

不行 。 从本质上讲,哈希德斯不保证是独一无二的。

不好的做法? 更重要的是,这是完全错误的。 两个不相等的对象可以返回相同的哈希码。 不要这样做。

这是从Object规范[JavaSE6]复制的契约:

如果根据equals(Ob- ject)方法两个对象不相等,则不需要在两个对象中的每一个上调用hashCode方法必须产生不同的整数结果。 但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。

要回答你的问题,不是。不是一个好主意。

正如Ryan Stewart所说,你编写的代码是错误的。

equals()中使用对象的哈希码可能有用的情况是当对象缓存哈希码时,确定相等性是非常昂贵的。 在这种情况下,您可以使用缓存哈希码的相等性作为早期必需但不充分的相等检查之一,对于大多数不equals()的对象,返回false fast。