在java的集合中,判斷兩個對象是否相等的規則是:
1),判斷兩個對象的hashCode是否相等
如果不相等,認為兩個對象也不相等,完畢
如果相等,轉入2)
2),判斷兩個對象用equals運算是否相等,相等就返回true
class Weibo
{
private String name;
publicWeibo (String name)
{
this.name = name;
}
// 根據name判斷兩個 weibo 是否相等
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o.getClass() == Name.class)
{
Weibo weibo = (Weibo)o;
return weibo.name.equals(name);
}
return false;
}
// 根據 first 計算 Name 對象的 hashCode() 傳回值
public int hashCode()
{
return name.hashCode();
}
public class HashSetTest
{
public static void main(String[] args)
{
HashSet<Weibo> set = new HashSet<Weibo>();
set.add(new Weibo("abc" );
set.add(new Weibo("abc" );
System.out.println(set);
}
}
執行結果:無法插入第二個對象。原因是什麼,因為要判斷hashcode,然後equals.
Weibo.hashcode中返回的是name,也就是說當name相同時,兩個weibo的hashcode就相同,這樣的話就開始判斷equals 一判斷是相同的。hashset
是不允許插入重複的。所以。
這就是hashset判斷對象是否相同的原理。
結論Hashtable、HashMap、HashSet、LinkedHashMap中的key,需要判斷該key對象的hashcode與equals。需要重寫這兩個方法。
hashcode用處,我們知道list與set區別,list中 元素是有序的,元素可以重複;set元素無序,但元素不可重複。 如果保證既有序又不可重複呢。 要想保證元素不重複,可兩個元素是否重複應該依據什麼來判斷呢。 這就是Object.equals方法了。但是,如果每增加一個元素就檢查一次,那麼當元素很多時,後添加到集合中的元素比較的次數就非常多了。
Java採用了雜湊表的原理, 雜湊演算法也稱為散列演算法,是將資料依特定演算法直接指定到一個地址上. 初學者可以這樣理解,hashCode方法實際上返回的就是Object Storage Service的物理地址(實際可能並不是)。
有了hashCode,當集合要添加新的元素時,先調用這個元素的hashCode方法,就一下子能定位到它應該放置的物理位置上。
如果這個位置上沒有元素,它就可以直接儲存在這個位置上,不用再進行任何比較了;如果這個位置上已經有元素了,
就調用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址。
所以這裡存在一個衝突解決的問題。這樣一來實際調用equals方法的次數就大大降低了,幾乎只需要一兩次.