今天面試遇到的一個問題,總結如下
問:如果有一個HashMap它的key是一個對象,如何保證這個key的唯一性?
答:重寫它的equals方法和hashcode方法
問:重寫equals方法的同時一定要重寫hashcode方法嗎?
答:是的,因為HashMap在put元素的時候是先判斷它的hashcode是否一樣,若一樣則調用equals比較,如果都一樣才認為這個key已經存在
代碼測試:
準備一個對象
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
p1和p2的屬性值都是相同
Person p1 = new Person("小明", 12);
Person p2 = new Person("小明",12);
引用資料類型的比較需要重寫equals方法,是以這裡重寫Person的equals方法
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
}
測試
if (p1.equals(p2)) {
System.out.println("p1等于p2");
}
HashMap<Person, String> map = new HashMap<>();
map.put(p1,"小明p1");
map.put(p2,"小明p2");
map.forEach((person, s) -> System.out.println("key:"+person.toString()+";value:"+s));
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL3YzN0M2Y0QzNjdjNkZGZ5EDM2QjY4ADNlNjZ1UzM4Q2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
很顯然這裡兩個相同的key,卻對應不同的value,這就與map中的key是唯一的相違背。
輸出p1和p2的hashcode
System.out.println("p1.hashCode() = " + p1.hashCode());
System.out.println("p2.hashCode() = " + p2.hashCode());
很顯然他們的hashcode是不相同的
這裡再重寫Person的hashcode方法
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
重寫hashcode方法後他們的hashcode相同
再嘗試将p1和p2同時put進map中
HashMap<Person, String> map = new HashMap<>();
map.put(p1,"小明p1");
map.put(p2,"小明p2");
map.forEach((person, s) -> System.out.println("key:"+person.toString()+";value:"+s));
而此時map中隻有小明p2
因為在同時添加p1和p2時間,map認為p1和p2是相等的,在加入p2時間已經有相同的key,而HashMap就會将相同key的value替換掉,而不再加入這個相同的key,這樣就保證了key的唯一性
為什麼在同時重寫hashcode和equals方法後便可以保證HashMap中key的唯一性?
因為HashMap在put元素的時候是先判斷它的hashcode是否一樣,若一樣則調用equals比較,如果都一樣才認為這個key已經存在