HashSet 關於 equals 和hashset方法


1  java類中HashSet添加對象時,為什么一定要重寫equals方法和HasCode方法?

a  Set集合沒有順序,也不允許重復,為什么會這樣?

答:是為了模擬現實的集合。

 

b  重復這里在現實中和內存中有什么區別?

答:現實中的重復指的是對象的重復,而內存中的重復指的hashCode的重復。

 

c  由於現實中和內存中的重復不同,存在一種情況,在內存中重復(hashCode)相同,現實中不是同一個對象,這種例子呢?

答:代碼如下,debug可以看到兩個person對象的hash碼相同,其屬性相同:

package com.array.set;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class TestHashSet2 {

    public static void main(String[] args) {

        Person p1 = new Person("a", 1);

        Person p2 = new Person("b", 0);

        Set<Person> set = new HashSet<Person>();

        set.add(p1);

        set.add(p2);

        Iterator<Person> it = set.iterator();

        while (it.hasNext()) {

            System.out.println(it.next().getName());

        }

    }

}

 

package com.array.set;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Set;

class Person {

    private String name;

    private int id;

    Person(String name, int id) {

        this.name = name;

        this.id = id;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getName() {

        return name;

    }

    public void setId(int id) {

        this.id = id;

    }

    public int getId() {

        return id;

    }

    public int hashCode() {

        return name.hashCode() + id; // 使用字符串哈希值與Integer的哈希值的組合

        // 這樣會產生重碼,實際上重碼率很高

    }

    public boolean equals(Object obj) {

        if (obj instanceof Person) { //

            Person p = (Person) obj;

            return (name.equals(p.name) && id == p.id);

        }

        return super.equals(obj);

    }

}

 

d  為了解決c這種情況(現實中的重復與內存的重復不一致),我們應該怎么做呢?

答:c代碼已經給了明顯的答案。

HashSet添加對象的時候,先用hashCode方法計算出該對象的哈希碼。

比較:

        (1),如果該對象哈希碼與集合已存在對象的哈希碼不一致,則該對象沒有與其他對象重復,添加到集合中!

        (2),如果存在於該對象相同的哈希碼,那么通過equals方法判斷兩個哈希碼相同的對象是否為同一對象(判斷的標准是:屬性是否相同)

                1>,相同對象,不添加。

                2>,不同對象,添加!

 

 

 

至此,1問題得到了解答。

  • 總思路:hashCode不同時,則必為不同對象。hashCode相同時,根據equlas()方法判斷是否為同一對象。
  • 在HashSet,HashMap,HashTable中都存在該問題。

 

2  為什么重寫Equals方法必須重寫HashCode方法?

答:1、將要傳入的數據根據系統的hash算法得到一個hash值;

  2、根據hash值可以得出該數據在hash表中的位置;

  3、判斷該位置上是否有值,沒有值則把數據插入進來;如果有值則再次判斷傳入的值與原值是否地址或equals相同,如果相同則不存,否則通過鏈表的方式 存儲到該位置。

如果兩個對象equals,但是沒有重寫hashcode,就會導致集合中可能存儲多個相等的對象!所以必須重寫!

 

引自:

https://jingyan.baidu.com/article/d5a880eb8fb61d13f147cc99.html

https://www.cnblogs.com/shew/p/11370804.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM