天天看點

如何保證HashMap中key的唯一性

今天面試遇到的一個問題,總結如下

問:如果有一個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));
           
如何保證HashMap中key的唯一性

很顯然這裡兩個相同的key,卻對應不同的value,這就與map中的key是唯一的相違背。

輸出p1和p2的hashcode

System.out.println("p1.hashCode() = " + p1.hashCode());
        System.out.println("p2.hashCode() = " + p2.hashCode());

           

很顯然他們的hashcode是不相同的

如何保證HashMap中key的唯一性

這裡再重寫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相同

如何保證HashMap中key的唯一性

再嘗試将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

如何保證HashMap中key的唯一性

因為在同時添加p1和p2時間,map認為p1和p2是相等的,在加入p2時間已經有相同的key,而HashMap就會将相同key的value替換掉,而不再加入這個相同的key,這樣就保證了key的唯一性

為什麼在同時重寫hashcode和equals方法後便可以保證HashMap中key的唯一性?

因為HashMap在put元素的時候是先判斷它的hashcode是否一樣,若一樣則調用equals比較,如果都一樣才認為這個key已經存在