当我看到equals()
方法的实现时,它除了==
之外什么也没做。所以我的问题是,当我们有==
运算符执行相同的工作时,需要将此作为单独的方法吗?
答案 0 :(得分:41)
您不能重载==
运算符,但如果您希望它与equals(Object)
运算符的行为不同,则可以覆盖==
,即不比较引用但实际比较对象(例如,使用他们的全部或部分领域。)
此外,如果您覆盖equals(Object)
,请同时查看hashCode()
。这两个方法需要兼容(即两个根据equals(Object)
相等的对象需要具有相同的hashCode()
),否则会发生各种奇怪的错误(例如,当将对象添加到集合中时)或地图)。
答案 1 :(得分:35)
==
比较对象引用,并询问这两个引用是否相同。
equals()
比较对象内容,并询问对象是否代表相同的概念。
答案 2 :(得分:18)
如果是原语, ==
操作符会检查两个值是否相同。
如果它不是原语,它会检查它是否是指向同一个对象实例的两个指针(或引用)。
equals()
方法使用Object
执行自定义检查,该检查位于==
检查引用中。但在其他类中,有时候equals()
被覆盖 (我不知道这是否是正确的过去分词) 。 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
)所以我希望现在很清楚。
答案 3 :(得分:2)
两者之间存在非常重要的差异。
“==”比较对象实例。默认的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(因为我们定义了2个人在具有相同名称时相等)
答案 4 :(得分:2)
==运算符用于比较引用 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())
如果将Collar定义为[如果Collar的颜色相同则衣领相同],则返回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;
}
}
答案 5 :(得分:1)
这样做是为了使这成为可能:
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()
以比较彼此的内部字符数组(实际值)。许多其他类也重写了这种方法。
答案 6 :(得分:0)
“string”==“string”将返回false “string”.equals(“string”)将返回true
使用o1 == o2比较对象1是与o2相同的对象(通过引用)
使用o1.equals(o2),取决于对象,equals方法被覆盖,而不是像“return o1 == o2”那样实现
例如,您创建2个Set实例 这两个对象是2个不同的对象,您可以在其中任何一个中添加不同的元素。 set1 == set2将始终返回false 但如果set2包含与set1完全相同的元素,则set1.equals(set2)最终将返回true,并且因为在Set类中覆盖了equals方法......
Set的等于实现是:
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
}
答案 7 :(得分:0)
在java equals中,如果操作数是原始数据类型,则operator(==)对两个变量的数据进行操作。但是如果操作数是对象,则java使用引用来比较它们,因为它无法比较对象的哪个或哪些字段。
因此,只有一种方法可以根据用户定义的字段进行比较,并且通过重写equals()方法在对象中定义,因为java中的equals运算符(==)不能覆盖,因为java不支持运算符覆盖。
作为一个例子,如果你想根据名称比较Employee,你需要通过覆盖Employee类中的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;
}
}