结论:我们都知道,如果是引用类型要作为hashmap的key或者set的值,需要重写hashCode()和equals方法。
那么如何重写hashCode()和equals方法以及技巧是什么呢?
1.hashCode()和equals方法在java中每个类都默认有,因为所有的类都是Object类的子类,可以查看Object的hashCode()和equals方法的默认实现,代码如下:
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
hashCode()方法是调用c底层的原生方法,equals()默认表示两个对象的存储地址是否相同。
2.测试
准备实体类:
static class User{
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdNum() {
return idNum;
}
public void setIdNum(String idNum) {
this.idNum = idNum;
}
private int age;
private String name;
private String idNum;
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
User user = (User) obj;
if (user.getIdNum().equals(this.idNum) && user.getName().equals(this.name) && user.getAge() == this.age) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
用equals测试是否相等:
public static void main(String[] args){
User user1 = new User();
user1.setAge(10);
user1.setName("Alice");
user1.setIdNum("000000000001");
User user2 = new User();
user2.setAge(10);
user2.setName("Alice");
user2.setIdNum("000000000001");
System.out.println("user1.equals(user2) == "+user1.equals(user2));
}
输出:
user1.equals(user2) == true
用Map和Set测试是否能作为Key:
public static void main(String[] args){
User user1 = new User();
user1.setAge(10);
user1.setName("Alice");
user1.setIdNum("000000000001");
User user2 = new User();
user2.setAge(10);
user2.setName("Alice");
user2.setIdNum("000000000001");
System.out.println("user1.equals(user2) == "+user1.equals(user2));
Map<User,Integer> map = new HashMap<>();
Set<User> set = new HashSet<>();
map.put(user1,10);
map.put(user2,10);
set.add(user1);
set.add(user2);
System.out.println("map.keySet().size() is: "+map.keySet().size());
System.out.println("set.size() is: "+set.size());
}
输出:
user1.equals(user2) == true
map.keySet().size() is: 2
set.size() is: 2
由此可以得出结论,引用类作为map的key需要重写hashCode
实体类User类重写hashCode后为:
static class User{
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdNum() {
return idNum;
}
public void setIdNum(String idNum) {
this.idNum = idNum;
}
private int age;
private String name;
private String idNum;
@Override
public int hashCode(){
int value = name.hashCode();
value = value*31 + idNum.hashCode();
value = value*31 + age;
return value;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
User user = (User) obj;
if (user.getIdNum().equals(this.idNum) && user.getName().equals(this.name) && user.getAge() == this.age) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
测试后size结果都是1了。