实施良好的平等方法
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' 参数。
假设我想在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' 参数。