1.hashcode是用來查找的,如果你學過數據結構就應該知道,在查找和排序這一章有
例如內存中有這樣的位置
0 1 2 3 4 5 6 7
而我有個類,這個類有個字段叫ID,我要把這個類存放在以上8個位置之一,如果不用hashcode而任意存放,那么當查找時就需要到這八個位置里挨個去找,或者用二分法一類的算法。
但如果用hashcode那就會使效率提高很多。
我們這個類中有個字段叫ID,那么我們就定義我們的hashcode為ID%8,然后把我們的類存放在取得得余數那個位置。比如我們的ID為9,9除8的
余數為1,那么我們就把該類存在1這個位置,如果ID是13,求得的余數是5,那么我們就把該類放在5這個位置。這樣,以后在查找該類時就可以通過ID除
8求余數直接找到存放的位置了。
2.但是如果兩個類有相同的hashcode怎么辦那(我們假設上面的類的ID不是唯一的),例如9除以8和17除以8的余數都是1,那么這是不是合法的,回答是:可以這樣。那么如何判斷呢?在這個時候就需要定義 equals了。
也就是說,我們先通過 hashcode來判斷兩個類是否存放某個桶里,但這個桶里可能有很多類,那么我們就需要再通過 equals 來在這個桶里找到我們要的類。
那么。重寫了equals(),為什么還要重寫hashCode()呢?
想想,你要在一個桶里找東西,你必須先要找到這個桶啊,你不通過重寫hashcode()來找到桶,光重寫equals()有什么用啊
hashCode()是用來產生哈希瑪的,而哈希瑪是用來在散列存儲結構中確定對象的存儲地址的,(這一段在 Java編程思想
中講的很清楚的)象util包中的 帶 hash 的集合類都是用這種存儲結構 :HashMap,HashSet,
他們在將對象存儲時(嚴格說是對象引用),需要確定他們的地址吧,
而HashCode()就是這個用途的,一般都需要重新定義它的,因為默認情況下,由 Object 類定義的 hashCode
方法會針對不同的對象返回不同的整數,這一般是通過將該對象的內部地址轉換成一個整數來實現的,現在舉個例子來說, 就拿HashSet來說
,在將對象存入其中時,通過被存入對象的 hashCode() 來確定對象在 HashSet
中的存儲地址,通過equals()來確定存入的對象是否重復,hashCode()
,equals()都需要自己重新定義,因為hashCode()默認前面已經說啦,而equals()
默認是比較的對象引用,你現在想一下,如果你不定義equals()的話,那么同一個類產生的兩個內容完全相同的對象都可以存入Set,因為他們是通過
equals()來確定的,這樣就使得HashSet 失去了他的意義,看一下下面這個:
import java.util.*;
/**
*類說明
* @author shellfeng E-mail:lsf830804@yahoo.com.cn
* @version 1.0
*
*/
public class Test {
public static void main(String[] args) {
HashSet set = new HashSet();
for (int i = 0; i <= 3; i++){
set.add(new Demo1(i,i));
}
System.out.println(set);
set.add(new Demo1(1,1));
System.out.println(set);
System.out.println(set.contains(new Demo1(0,0)));
System.out.println(set.add(new Demo1(1,1)));
System.out.println(set.add(new Demo1(4,4)));
System.out.println(set);
}
private static class Demo1 {
private int value;
private int id;
public Demo1(int value,int id) {
this.value = value;
this.id=id;
}
public String toString() {
return " value = " + value;
}
public boolean equals(Object o) {
Demo1 a = (Demo1) o;
return (a.value == value) ? true : false;
}
public int hashCode() {
return id;
}
}
}
你分別注釋掉hashCode()和 equals()來比較一下他們作用就可以拉,關鍵要自己動手看看比較的結果你就可以記得很清楚啦
結果:
[ value = 2, value = 1, value = 3, value = 0]
[ value = 2, value = 1, value = 3, value = 0]
true
false
true
[ value = 2, value = 4, value = 1, value = 3, value = 0]
注釋掉hashCode()
[ value = 1, value = 0, value = 2, value = 3]
[ value = 1, value = 0, value = 1, value = 2, value = 3]
false
true
true
[ value = 1, value = 0, value = 1, value = 2, value = 3, value = 4, value = 1]
注釋掉equals()
[ value = 2, value = 1, value = 3, value = 0]
[ value = 2, value = 1, value = 1, value = 3, value = 0]
false
true
true
[ value = 2, value = 4, value = 1, value = 1, value = 1, value = 3, value = 0]
hashCode()方法使用來提高Map里面的搜索效率的,Map會根據不同的hashCode()來放在不同的桶里面,Map在搜索一個對象的時候先
通過hashCode()找到相應的桶,然后再根據equals()方法找到相應的對象.要正確的實現Map里面查找元素必須滿足一下兩個條件:
(1)當obj1.equals(obj2)為true時obj1.hashCode() == obj2.hashCode()必須為true
(2)當obj1.hashCode() == obj2.hashCode()為false時obj.equals(obj2)必須為false