![](/img/trans.png)
[英]Comparing two different objects using contains(Object o) returns false, when equals(Object o) returns true
[英]How equals method returns false when comparing two objects: e1.equals(e2)
class Emp {
public Emp(String s) {
}
}
public class Testing {
public static void main(String[] args) {
Emp e1 = new Emp("hello");
Emp e2 = new Emp("hello");
System.out.println(e1 == e2);
System.out.println(e1.equals(e2));
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
输出IS: false false false true
如果您不覆盖方法的hashcode
和equals
,则默认的equals
方法如果位于相同的内存位置,则将返回true。 由于e1
和e2
是单独的对象,因此它们位于单独的内存位置,因此没有覆盖equals
, e1.equals(e2)
将为false。
为了使e1.equals(e2)
返回true, Object
的equals
的默认实现应返回true(这要求e1==e2
),或者您应以返回的方式重写Emp
类中的equals
应用于e1
和e2
实例时为true。
“ Emp”类从根“ OBJECT”类继承了equals()方法。
以下是Object类中存在的equals()方法代码:
public boolean equals(Object obj)
{
return (this == obj);
}
正如您在上面看到的那样,该命令检查内存位置地址是否相等。
第一种情况:
Emp e1 = new Emp("hello");
Emp e2 = new Emp("hello");
System.out.println(e1 == e2);
在这里,您正在比较reference(内存位置),因为您在堆中创建了两个新对象,因此内存位置不同,因此将其重新调整为“ false”
第二种情况:
Emp e1 = new Emp("hello");
Emp e2 = new Emp("hello");
System.out.println(e1.equals(e2));
在这里,您将涉及从“ Object”类继承的equals()方法,该方法依次检查这两个对象的引用(内存位置),并因此重新设置为false。
第三种情况:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);
在这种情况下,String类具有被覆盖的equals()方法,该方法实际上检查对象字段以进行比较,以下是String类中equals()方法的源代码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
这与第一种情况类似,在这里您将比较两个字符串对象的reference(内存位置),因为您在堆中创建了两个新对象,因此内存位置不同,因此将其调整为“ false”
第四种情况:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1.equals(s2));
在这里,您要从字符串类(上面粘贴的代码)中调用重写的equals()方法。 如果您看到逻辑,它首先实际检查两个引用是否指向相同的内存位置(如果相同),则返回true,否则它将实际检查由charcter数组支持的两个字符串对象的内容,并将每个对象进行比较这些拖曳字符串对象的核心字符对应的字符,因为两个对象的内容都相同“ hello”,所以返回true。
正如Ken前面提到的,请通过equals()和hashcode()契约。
System.out.println(e1 == e2); <-- A
System.out.println(e1.equals(e2)); <-- B
System.out.println(s1 == s2); <-- C
System.out.println(s1.equals(s2)); <-- D
Object
类。 因此,equals方法的实现是使用Object
类中定义的方法,该方法与表达式A相同。 String
类具有自己的equals
函数实现,该函数检查字符串的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.