equals(Object obj)做什么?
我经常在不同的地方找到一种平等的方法。 它实际上做了什么? 重要的是我们必须在每个class级都有这个吗?
public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null) { return false; } if (obj instanceof Contact) { Contact other = (Contact)obj; return other.getFirstName().equals(getFirstName()) && other.getLastName().equals(getLastName()) && other.getHomePhone().equals(getHomePhone()) && other.getCellPhone().equals(getCellPhone()); } else { return false; } }
它重新定义了对象的“平等”。
默认情况下(在java.lang.Object
定义),只有当对象是同一个实例时,该对象才等于另一个对象。 但是,当您覆盖它时,您可以提供自定义相等逻辑。
例如, java.lang.String
通过比较内部字符数组来定义相等性。 这就是为什么:
String a = new String("a"); //but don't use that in programs, use simply: = "a" String b = new String("a"); System.out.println(a == b); // false System.out.println(a.equals(b)); // true
即使您可能不需要像这样测试相等性,您使用的类也可以。 例如, List.contains(..)
和List.indexOf(..)
使用.equals(..)
。
检查javadoc以获取equals(..)
方法所需的确切契约。
在许多情况下,当重写equals(..)
您还必须覆盖hashCode()
(使用相同的字段)。 这也是在javadoc中指定的。
不同的类具有使2个对象“相等”的不同标准。 通常,如果equals()是同一个Object,则返回true:
Object a = new Object(); Object b = new Object(); return(a.equals(b));
这将返回false,尽管它们都是“对象”类,但它们不是同一个实例。 a.equals(a)
将返回true。
但是,在类似String的情况下,您可以有2个不同的实例,但字符串相等性基于构成这些字符串的文字字符:
String a = new String("example"); String b = new String("example"); String c = new String("another"); a.equals(b); a.equals(c);
这些都是String的不同实例,但是第一个equals将返回true,因为它们都是“example” ,但第二个不会因为“example”不是“another”。
只有当存在相等的特殊情况时,您才需要为每个类重写equals(),例如包含3个字符串的类,但只有第一个String用于确定相等性。 在您发布的示例中,可能有另一个字段, description
可能对于2个不同的“联系人”不同,但如果这4个条件匹配(第一个/最后一个名称和家庭/手机),则2个“联系人”将被视为相等数字),而匹配或不匹配的描述不会影响2个联系人是否相等。
除了Bozho提供的所有内容之外,还有一些其他事项需要注意,如果重写等于:
-
.equals(null)
必须始终返回false – 即null不等于其他任何东西。 在您的代码的第二个if中处理此要求。 -
如果确实某些东西 == 其他东西 ,那么还有东西
.equals(
别的东西)
也必须是真的。 (即相同的对象必须相等)代码的第一个if处理这个问题。 -
.equals
应该是非空对象的对称,即a.equals(b)
应该与b.equals(a)
相同。 有时,如果您在父类和子类中进行子类化和重写equals,则此要求会中断。 通常equals包含像if (!getClass().equals(other.getClass())) return false;
这至少可以确保不同的对象类型彼此不相等。 -
如果重写
equals
你也必须覆盖hashCode
,使得以下表达式成立:if (a.equals(b)) assert a.hashCode() == b.hashCode()
。 即两个彼此相等的对象的哈希码必须相同。 请注意,反之亦然:具有相同哈希码的两个对象可能彼此相同也可能不相同。 通常,通过从用于确定对象相等性的相同属性派生hashCode来处理此要求。
在您的情况下,hashCode方法可以是:
public int hashCode() { return getFirstName().hashCode() + getLastName().hashCode() + getPhoneHome().hashCode() + getCellPhone().hashCode(); }
- 如果你实现
Comparable
比较两个对象,如果它们相互之间更小,更大或相等,当和仅当a.equalTo(b) == true
,a.compareTo(b) == 0
应为a.equalTo(b) == true
在许多IDE(例如Eclipse,IntelliJ IDEA,NetBeans)中,有一些function可以为您生成equals
和hashCode
,从而使您免于繁琐且可能容易出错的工作。
当想要通过对象找到合适的任何定义来知道两个对象是否相等时,使用equals
方法。 例如,对于String
对象,等效性是关于两个对象是否表示相同的字符串。 因此,类通常提供自己的equals
实现,这些实现以该类的自然方式工作。
equals
方法与==
不同之处在于后者测试对象标识,即对象是否相同(不一定与等效对象相同)。
它使您能够重新定义哪些对象相等以及哪些不相等,例如,如果Person.ID
相同或者权Weight
相等,则可以将两个Person
对象定义为相等,具体取决于应用程序中的逻辑。
请参阅: 覆盖java equals()方法的quirk
- 扩展Android的默认Gmail /电子邮件应用程序
- 如何将System.getProperty(“user.dir”)更改为项目工作区
- 在java中修剪一个字符串以获得第一个单词
- 使用GPS(LocationManager)如何获取当前时间?
- 如何发送请求标题是“内容类型”:“应用程序/ json”在排球时获取
- 我得到:错误:任务’:app:transformClassesWithDexForDebug’的执行失败。 制作Google地图应用时
- 如何在地图上放置JSON lOutput(纬度和经度)
- android ant error:无效的资源目录名:./ bin / res \ crunch
- 使用Oauth将Java应用程序与GAE应用程序连接起来