1. 程式人生 > >equals與hashcode的關係

equals與hashcode的關係

1、hashcode方法和equals方法都是Object類中的方法,Object類對equals方法進行了定義,比較的是兩個物件的引用來確定比較的物件是否是同一個物件;

而Object類沒有對hashcode方法進行定義。

2、當物件類需要進行比較或者插入到集合中時,需要重寫equals方法和hashcode方法,同時要保持兩個方法返回結果一致

3、equals方法一般用於物件例項內容的比較,而hashcode方法一般用於集合中用到;

集合使用步驟:

(1)物件放入到 集合中時,首先需要比較放入物件的hashcode值是否與原有集合中的元素重複(hashcode方法),如果不相等就直接放入到集合中;

(2)如果hashcode值相等,則再次比較equals方法,如果該方法返回值不一致就可以插入到集合中,但如果也相等,則不能插入到集合中

注:一般hashcode方法主要用在使用hash結構的類中,比如HashSet、HashTable、HashMap中等;在hash結構中還存在同一個hash值對應的桶的結構(實際上是一個數組),如果hash值相同,然後equals方法不同,則會放入到同一個位置的桶結構中。

具體程式碼:

測試程式碼:(沒有重寫equals方法)

LinkedList<Person> list = new LinkedList<>();

// 連結串列有序集合(可以插入重複內容)
Set<Person> set = new HashSet<>();

Person p1 = new Person();
Person p2 = new Person();

p1.setAge(12);
p1.setName("p");

p2.setAge(12);
p2.setName("p");

System.out.println("p1 == p2:" + (p1 == p2));// == 比較的是其值是否相同
System.out.println("p1 equals p2" + (p1.equals(p2)));// 呼叫Object的equals,判斷是否是同一個物件

list.add(p1);
list.add(p2);

set.add(p2);
set.add(p1);
System.out.println(list.size());
System.out.println(set.size());

結果:

p1 == p2:false
p1 equals p2false
2
2

程式碼測試:(重寫equals方法)

p1 == p2:false
p1 equals p2false
2
2

程式碼測試:(重寫hashcode方法)

p1 == p2:false
p1 equals p2 :true
2
2

程式碼測試:(兩個都重寫)

p1 == p2:false
p1 equals p2 :true
2
1

另外,說到hashcode方法了,就再說一下HashSet集合和HashMap集合的淵源:

HashSet集合在底層也是使用HashMap來實現元素的儲存,只是將元素本身作為key,而value是一個Object物件(未知);而HashMap集合在底層是通過一個泛型動態陣列來儲存資料的:transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;

這個泛型動態陣列初始化大小是16,,負載因子是0.75,當插入的元素個數達到陣列大小*0.75時

泛型陣列每次增長都是變為原來的二倍;(利用空間換時間來提高讀取速度)

同時泛型動態陣列中又包含桶的結構,類似於c中的連結串列陣列,桶中儲存的都是hash值相同的元素;

如圖: