与==的关系
java中Object的中定义的equals方法是这样的:
public boolean equals(Object obj) {
return (this == obj);
}
这样来看,在子类没有重新定义equals方法的情况下,equals方法是跟”==“没有区别的。
重写equals
为了满足我们的需求,通常我们需要根据需求自定义equals方法。
String中的重写
在String类中,是这样重写的:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
代码中的value是一个char数组,存储了String字符串中的每一个字符。
可以看出String的equals方法的判断条件是:
判断两个对象是否是同一个对象,是的话就返回true,相当于是Object中的equals。
判断被比较的对象是否是String对象或者String对象的派生类,否的话返回false。
判断两个对象中的字符个数是否相同,否的话返回false。
依次比较两个对象中的每个字符是否相等,一旦出现不同,返回false。
以上所有比较通过,返回true。
测试:
public static void main(String[] args) throws CloneNotSupportedException {
String s1 = new String("helloworld");
String s2 = new String("helloworld");
char[] s3 = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'};
if(s1.equals(s2)) {
System.out.println("s1.equals(s2) == true"); //s1.equals(s2) == true
}
if(!s1.equals(s3)) {
System.out.println("s1.equals(s3) == false"); //s1.equals(s3) == false
}
自己编写equals的一些建议
1.显示参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量。
2.检测this与otherObject是否引用同一个对象:
if(this == otherObject)
return true;
3.检测otherObject是否为null,如果为null,返回false。这项检测是很有必要的
if(otherObject == null)
return false;
4.比较this与otherObject是否属于同一个类。如果equals的语义在每一个子类中有所变化,就是用getClass检测:
if(!(getClass != otherObject.getClass())
return false;
如果所有子类都拥有统一的语义,就使用instanceof检测:
if(!(otherObject instanceof ClassName))
return false;
5.将otherObject转化为相应的类类型变量:
ClassName other = (ClassName) otherObject
6.现在就可以开始对所有需要比较的域进行比较了。使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,就返回true;否则返回false。
return field1 == other.field1
&& Objects.equals(field2., other.field2)
&&...;
如果在类中重新定义equals,就要在其中包含调用super.equals(other)。
网友评论