考虑将等式方法添加到以下类简单点:
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
// ...
}
//我对equals的定义
public boolean equals(Point other) {
return (this.getX() == other.getX() && this.getY() == other.getY());
}
这种方法有什么问题?乍一看,似乎工作正常:
Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
Point q = new Point(2, 3);
System.out.println(p1.equals(p2)); // prints true
System.out.println(p1.equals(q)); // prints false
但是,一旦开始将积分放入集合中,麻烦就会开始:
import java.util.HashSet;
HashSet<Point> coll = new HashSet<Point>();
coll.add(p1);
System.out.println(coll.contains(p2)); // prints false
即使p1被添加到它,并且p1和p2是相等的对象,它怎么可能不包含p2?
答案 0 :(得分:8)
虽然您在实施hashCode()
时应该实施equals()
,但这不会导致您的问题。
这不是您正在寻找的equals()
方法。 equals方法必须始终具有以下签名:“public boolean equals(Object object)”。这是一些代码。
public boolean equals(Object object)
{
if (object == null)
{
return false;
}
if (this == object)
{
return true;
}
if (object instanceof Point)
{
Point point = (Point)object;
... now do the comparison.
}
else
{
return false;
}
}
Apache EqualsBuilder class对于equals实现非常有用。该链接是旧版本,但仍然适用。
如果您喜欢Apache EqualsBuilder,您可能也会喜欢Apache HashCodeBuilder class。
编辑更新了标准快捷方式的等于方法示例。
答案 1 :(得分:4)
每当您覆盖hashCode()
时,您必须实施equals()
。这两者协同工作,必须始终提供一致的结果。如果不这样做,就会产生你观察到的错误行为。
这将更详细地解释,例如在Effective Java 2nd Edition中,第9项:覆盖等于时始终覆盖hashCode。
答案 2 :(得分:2)
通过覆盖哈希码来运行良好!
永远记住:覆盖等于时覆盖hashCode。
@Override public int hashCode() {
return (41 * (41 + getX()) + getY());
}
这是我对hashCode的实现。
答案 3 :(得分:1)
根据equals()
上的合同,您还需要实施hashCode()
。
来自equals()
上的JavaDoc:
请注意,通常需要在重写此方法时覆盖hashCode方法,以便维护hashCode方法的常规协定,该方法声明相等的对象必须具有相同的哈希代码。
答案 4 :(得分:1)
除了其他答案:
如果您使用Eclipse作为IDE,则只需使用&#34; Source&#34; - &GT; &#34;生成hashCode()和equals()以获得基本实现。随便做你想做的事。
答案 5 :(得分:0)
覆盖equals
时,您还必须覆盖hashCode
(特别是,如果您要使用HashSet
或HashMap
...)。一个合适的(虽然不聪明)实现将是:
int hashCode() {
return x * 31 + y;
}
另一点(没有双关语):你实际上并没有覆盖类equals(Object)
中定义的Object
方法,而是定义了一个新方法。正确的方法是:
boolean equals(Object other) {
if (other == this) return true;
else if (!(other instanceof Point)) return false;
else {
Point p = (Point)other;
return x == p.getX() && y == p.getY();
}
}
请注意,equals
方法与pretty strong contract相关联,您要完成此操作。