No.4.1 HashSet

有上一節可以知道,HashSet底層存儲方式是按照存儲元素的Hash值來確定的,Set集合不能重復,也跟元素的HashCode值不同有關;
使用HashSet來存儲自定義類對象,必須在對象類內部實現HashCode方法和equal方法。

HashSet判斷儲存元素是否重復的方法:

(1)在向Set集合中存放元素時,Set集合根據元素的hashCode()方法來獲取一個int類型的數據,然后根據這個數據來計算元素在集合中的位置。但是在存儲元素時會出現兩個元素的hashCode()方法返回值相同的情況。
(2)如果發生了返回值相同的情況,Set集合會根據發生沖突元素之間調用equals()方法進行比較,如果equals()返回值為true,說明兩個元素為相同的元素,這樣會導致添加操作無效。如果equals()返回值為false,說明兩個元素不相同,這樣Set集合會將該元素進行偏移存儲。
(3)元素hashcode值相同發生的頻率越高,Set集合的性能就越低,要盡可能的避免沖突的發生, 就要在類中重寫hashCode()方法,并且要盡可能的保證hashCode()方法返回值是唯一的。
(4)在重寫hashCode()方法時有個技巧,就是讓對象中的數值屬性和一個素數相乘,并將積相加,獲取對象類型的hashcode,調用其hashCode()方法即可得到。

驗證HashSet存儲基本數據類型元素不可重復性:

public class HashSetDemo {
public static void main(String[] args){
    HashSet hs = new HashSet();
    hs.add("a");
    hs.add("c");
    hs.add("d");
    hs.add("a");
    for(Iterator it = hs.iterator(); it.hasNext();){
        System.out.println(it.next());
    }//d c a
    for(Object str : hs){
        System.out.println(str);
    }// da c a
}
}

Set存儲自定義類對象,元素重復的現象:

public class HashSetDemo {
public static void main(String[] args){
    HashSet hs = new HashSet();
    Person p1 = new Person(1, "lili");
    Person p2 = new Person(2, "lili");
    Person p3 = new Person(2, "lili");
    
    hs.add(p1);
    hs.add(p2);
    hs.add(p3);
    
    System.out.println(hs.size());
    
    for(Iterator it = hs.iterator(); it.hasNext();){
        System.out.println(it.next());
    }
}
}

上述例子運行結果為:
3
[ id: 1,name: lili]
[ id: 2,name: lili]
[ id: 2,name: lili]
由此可見,如果我們不再自定義類中中定義元素是否相同的兩個比較方發(HashCode和equals)那么,set集合很可能就判斷不出我們存儲了重復元素;
如果我們在地定義的Person類中覆寫了hashcode和equals方法那么運行結果就不存在重復元素了;
eclipse字節就可以根據我們所需要的屬性值來生成這兩個方法:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + Id;
    result = prime * result + ((name == null) ? 0 : name.hashCode());//如果姓名為空則表達式值為0;
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (Id != other.Id)
        return false;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容