实施良好的平等方法

Implementing good equals method

假设我想在Java中创建一个名为Foo的新class,它有2个成员变量,int bar double temp,我想给 class 一个比较 class 和 returns 的两个实例的 equals 方法一个布尔值。我有 2 个 Foo 实例,f1 和 f2。假设正确定义了构造函数,很多人会告诉我这样做:

public boolean equals(Foo f2)
{
    return (bar  == f2.getBar() && 
            temp == f2.getTemp());
}

在哪里检查相等性,你会做

f1.equals(f2);

但是,我很确定我见过有人这样做:

public static boolean equals(Foo f1, Foo f2)
{
    return (f1.getBar()  == f2.getBar() && 
            f1.getTemp() == f2.getTemp());
}

在哪里检查相等性,你会做

Foo.equals(f1, f2);

我的问题是,既然我已经看过这两种实现,那么这两种实现中哪一种被认为是更好的编程风格?

这两个代码片段代表不同的实现,将用于不同的目的。

public boolean equals(Foo f2)
{
    return (bar  == f2.getBar() && 
            temp == f2.getTemp());
}

该代码段将在 Foo class 中实现,它会检查另一个 Foo

其中

public static boolean equals(Foo f1, Foo f2)
{
    return (f1.getBar()  == f2.getBar() && 
            f1.getTemp() == f2.getTemp());
}

是你传的一个util,两个Foo's是check equality

标准 Java 类 like HashMap 期待方法 like

public boolean equals(Object obj)
//                    ^^^^^^

没有

public boolean equals(Foo f2)

这意味着它将使用从您的超类继承的 equals(Object obj)(因此,如果超类是 Object,它将最终在内部使用 ==)。

所以这两种方法都只是额外的方法,它们可能同样好也可能同样坏,具体取决于您要如何使用它们。 IMO equals(Foo f2) 稍微差一些,因为它会导致与 equals(Object o).

混淆

你最好使用非静态版本,因为它会覆盖 Object.equals 方法,java 会在你不知道的时候调用它,比如当你的 Foo 对象是在集合中,然后调用 myList.contains(myfooInstance)。如果你只实现静态版本,当 java 需要知道两个 Foo 对象是否相等时,它不会被调用。但正如 Phesmo 所述,您需要使用 'Object' 参数而不是 'Foo' 参数。