案例
package cn.itcast_02; import java.util.HashSet; /* * 需求:存儲自定義對象,並保證元素的唯一性 * 要求:如果兩個對象的成員變量值都相同,則為同一個元素。 * * 目前是不符合我的要求的:因為我們知道HashSet底層依賴的是hashCode()和equals()方法。 * 而這兩個方法我們在學生類中沒有重寫,所以,默認使用的是Object類。 * 這個時候,他們的哈希值是不會一樣的,根本就不會繼續判斷,執行了添加操作。 */ public class HashSetDemo2 { public static void main(String[] args) { // 創建集合對象 HashSet<Student> hs = new HashSet<Student>(); // 創建學生對象 Student s1 = new Student("林青霞", 27); Student s2 = new Student("柳岩", 22); Student s3 = new Student("王祖賢", 30); Student s4 = new Student("林青霞", 27); Student s5 = new Student("林青霞", 20); Student s6 = new Student("范冰冰", 22); // 添加元素 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); hs.add(s5); hs.add(s6); // 遍歷集合 for (Student s : hs) { System.out.println(s.getName() + "---" + s.getAge()); } } }
過程插圖:
System.out.println(new Student().hashCode()==new Student().hashCode());//false
System.out.println(new Student("范冰冰",28).hashCode()==new Student("范冰冰",28).hashCode());//false
上面的代碼說明:成員變量的值完全相等的兩個對象,如果不重寫hashCode()方法,而是用Object類的,結果都不相等。
所以在是用HashXX集合時,多個對象的hashCode()都不相同,造成了多個bucket,每個bucket中的元素很少,不高效。
//equals()方法相同,一定要保證hashCode()結果也相同
//而hashCode()相同,則不能說他們的equals()結果相同。
1 不重寫hashCode,和equals HashXX集合中將一定可以存儲重復的該類對象
2 不重寫hashCode,重寫equals bucket 多,每個bucket中的元素少
3 重寫hashCode,重寫equals 可以保證HashXX集合的唯一性
equals重寫:自己定義規則
hashCode重寫: 引用類型.hashCode()+基本類型*素數
元素在存入HashXX集合之后,不應當修改參與hashCode()運算的對象屬性的值,否則會因為找不到bucket 而造成內存泄露。