我无法理解String类中equals
方法的行为(区分),然后在自定义类中手动覆盖equals
方法。
根据java,如果我们希望两个对象相等,那么我们应该重写equals
方法以检查它们之间的相等性。因此,我制作了一个Dog
类并在该类中重写equals方法。为了进一步检查对象之间的相等性,我使用了Set
类型集合,因为它不允许重复。但是我很困惑看到输出。这是我的代码:
import java.util.*;
class Dog{
int type;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public boolean equals(Object o){
if((o instanceof Dog) && ((Dog)o).getType()==this.getType()){
return true;
}
else{
return false;
}
}
}
public class CheckEquality {
public static void main(String[] args) {
Dog d1=new Dog();
Dog d2=new Dog();
d1.setType(12);
d2.setType(12);
Set set=new HashSet();
if(set.add(d1)){
System.out.println("d1 added");
}
if(set.add(d2)){
System.out.println("d2 added");
}
String s1=new String("ad");
String s2=new String("ad");
//String s1="ad";
//String s2="ad";
Set set2=new HashSet();
if(set2.add(s1)){
System.out.println("s1 added");
}
if(set2.add(s2)){
System.out.println("s2 added");
}
}
}
输出:
d1 added
d2 added
s1 added
我期望的是:
d1 added
s1 added
谁能告诉我为什么得到d2 addedd
语句,当可以看到具有相同type
的对象已经被添加到Set
时。
相反,String不允许语句s2 added
。为什么会这样呢?任何人都可以消除我的疑虑。
因为还必须覆盖hashCode
。检查Object#equals
的合同:
[注意,通常必须重写hashCode方法,以保持hashCode方法的常规约定,该约定规定相等的对象必须具有相等的哈希码。
将此添加到您的Object#equals
类:
Dog
这只是一个基本示例。如果public class Dog {
@Override
public int hashCode() {
return this.type;
}
}
是type
字段会更好。从final
:
[只要在Java应用程序执行期间在同一对象上多次调用它,则
Object#hashCode
方法必须一致地返回相同整数,前提是未修改该对象的相等比较中使用的信息。从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。
如果不重写哈希码方法,则在将对象存储在哈希集中时会出现冲突问题。哈希集在内部使用哈希表来键和值对。
因为您必须重写哈希码,以便哈希集找到相同的哈希码,然后它将在内部调用equals方法。
type