当我查看equals()
方法的实现时,它什么也不做,与==
操作符所做的一样。因此我的问题是,既然有==
操作符可以完成相同的工作,为什么还需要将其作为独立的方法存在呢?
当我查看equals()
方法的实现时,它什么也不做,与==
操作符所做的一样。因此我的问题是,既然有==
操作符可以完成相同的工作,为什么还需要将其作为独立的方法存在呢?
你不能重载==
运算符,但是如果你想让它的行为与==
运算符不同,即不仅比较引用还要实际比较对象(例如使用所有或一些字段),则可以重写equals(Object)
方法。
另外,如果你重写equals(Object)
方法,也要查看hashCode()
方法。这两个方法需要兼容(即根据equals(Object)
方法相等的两个对象需要具有相同的hashCode()
值),否则会发生各种奇怪的错误(例如当将对象添加到集合或映射中时)。
==
比较对象的引用(reference),并询问这两个引用是否相同。
equals()
比较对象的内容(contents),并询问这些对象是否代表相同的概念。
对于基本类型,==
运算符检查两个值是否相同。如果不是基本类型,则检查它们是否是指向同一对象实例的两个指针(或引用)。
equals()
方法执行自定义检查,在Object
中通过使用==
检查引用。但是在其他类中,有时会重写 equals()
方法,它必须检查内容。
例如:
int i0 = 34;
int i1 = 34;
int i2 = 35;
// results
i0 == i1: true
i1 == i0: true
i2 == i0: false
但是如果我们有非基本类型
String str0 = new String("Hello man!");
String str1 = new String("Hello man!");
String str2 = new String("!nam olleH");
String str2copy = str2;
// Results
str0 == str1: false // Pointer to two different object, so == will give false
str1 == str2: false // Idem
str2 == str2copy: true // So this are two pointers to the same object
str0.equals(str1): true // This are not the same objects, but they are equal
str1 == str1: true // Again: two times a pointer to the same object
所以,为什么str0.equals(str1)
返回true
? 因为String类覆盖了equals()
方法。在这个方法中,它不通过执行return this == obj;
来检查它们是否相等。但在这个方法中,有一个完整的检查过程。我不知道他们用哪种方法来比较两个字符串,但这里有两种可能的方式:
int == int
)这两者之间有非常重要的区别。
"==" 比较对象实例。默认的 equals() 方法也是这样做的。请运行并分析以下代码示例:
public class Person{
String name;
public Person(String name){
this.name = name;
}
//overriding equals
public boolean equals( Object obj ) {
if( this == obj )
return true;
if( obj == null )
return false;
if( getClass() != obj.getClass() )
return false;
Person other = (Person) obj;
if( name == null ) {
if( other.name != null )
return false;
} else if( !name.equals( other.name ) )
return false;
return true;
}
}
...
...
Person john1 = new Person("John");
Person john2 = new Person("John");
System.out.println("john1 == john2:" + (john1 == john2));
System.out.println("john1.equals(john2):" + john1.equals(john2));
正如您所看到的,“==”会返回false(这两个Person对象是不同的实例),而equals将返回true(因为我们定义了当两个Person具有相同的名称时它们是相等的)。
"==" 运算符用于比较引用。 equals() 方法是在对象定义上定义的。
Dog d =new Dog();
Collar c =new Collar("Red");
d.setCollar(c);
Dog d2=new Dog();
Collar c2=new Collar("Red");
d2.setCollar(c2);
d2.getCollar() ==d.getCollar()
返回 false,表示这两只狗有两个不同的项圈对象。它们不共享相同的项圈。
d2.getCollar().equals(d.getCollar())
如果颈圈定义为[颈圈的颜色相同,则颈圈相同],则返回true。 这两只狗有相同颜色的颈圈。
class Collar{
String color="";
public Collar(String p0){
this.color=p0;
}
boolean equals(Object c){
Collar other=(Collar)c;
return this.color.equals(other.getColor());
}
public String getColor(){
return this.color;
}
}
这样做是为了使这成为可能:
String s1 = new String("foo");
String s2 = new String("foo");
System.out.println(s1 == s2); // false?! Different references!
System.out.println(s1.equals(s2)); // true
如果你查看String#equals()
的源代码,你会发现它已经适当地重写了Object#equals()
方法,以比较彼此的内部字符数组(即实际值)。许多其他类也对这个方法进行了重写。
public class Employee {
private Integer id;
private String name;
@Override
public boolean equals(Object obj) {
Employee other = (Employee) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
字符串 "string" == "string" 将返回 false。 "string".equals("string") 将返回 true。
使用 o1 == o2 比较对象 1 是否与 o2 相同(按引用比较)。
对于 o1.equals(o2),根据对象,equals 方法可能被重写并且不会实现类似于 "return o1 == o2" 的内容。
例如,您创建了两个 Set 实例。这两个 set 对象是两个不同的对象,您可以在任何一个对象中添加不同的元素。set1 == set2 总是返回 false,但是如果 set2 包含与 set1 完全相同的元素,则 set1.equals(set2) 最终将返回 true,并且因为 Set 类中已重写 equals 方法...
Set 的 Equals 实现为:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Set s = (Set) o;
if (s.size() != c.size())
return false;
return containsAll(s); // Invokes safe containsAll() above
}
string1 == string2
和 string1.equals(string2)
—— 你回答中的这两个例子都会返回 false。 - Samir Talwar