建立一個物件模型的時候,為什麼要重寫hashCode與equals方法
阿新 • • 發佈:2019-01-01
為了闡明其作用,我們先來假設有如下一個Person類。
class Person { public Person(String name, int age) { this.name = name; this.age = age; } private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "{" + name + ", " + age + "}"; } }
現在有很多Person類的物件需要儲存,很自然聯想到用HashSet來儲存,於是乎,寫了下面的程式來測試一下:
import java.util.*; public class HashSetDemo { public static void main(String[] args) { Collection set = new HashSet(); set.add(new Person("張三", 21)); set.add(new Person("李四", 19)); set.add(new Person("王五", 22)); set.add(new Person("張三", 21)); sop(set); } private static void sop(Collection set) { Iterator it = set.iterator(); while (it.hasNext()) { Person p = it.next(); System.out.println(p.toString()); } } }
在儲存的時候,我故意存了兩個“21歲的張三”,我的本意是這是同一個人,也就是說set集合裡面只需要出現一個“21歲的張三”,可事實是:
出現了兩個一樣的張三,為什麼會這樣呢?
其實,在往HashSet集合放置元素時,會根據其hashCode來判斷兩個元素是否一樣,如果是一樣,這後者覆蓋前者。而hashCode預設是比較其地址值。於是,對於兩個new 出來的“21歲的張三”,其地址值不一樣,所以HashSet才將兩個均加入其中。
為了達到只存放一個的目的,我們必須重寫hashCode方法,當然與其緊密聯絡的equals方法也要重寫,新的Person類如下:
class Person { //都一樣,變化的就是下面的 public int hashCode() { return name.hashCode() + age * 10; } public boolean equals(Object obj) { if (!(obj instanceof Person)) throw new ClassCastException("型別不匹配"); Person p = (Person) obj; return this.name.equals(p.getName()) && this.age == p.getAge(); } }
此時,再執行重寫,結果如下:
總結:一般對於存放到Set集合或者Map中鍵值對的元素,需要按需要重寫hashCode與equals方法,以保證唯一性!
看完這連著的三篇文章,就可以回答為什麼set新增資料不會重複,他呼叫了每個物件的hashcode方法和equal方法來判斷是不是同一個物件,然後再考慮我要不要新增到我的set集合裡面去。