只有用到Hashtable、HashMap、HashSet、LinkedHashMap等時才要注意hashcode,其他地方hashcode無用。(這麼理解不一定對)
判斷兩個對象是否相等是否要求hashcode() 相等,下邊的說法是否對
在java的集合中,判斷兩個對象是否相等的規則是:
1),判斷兩個對象的hashCode是否相等
如果不相等,認為兩個對象也不相等,完畢
如果相等,轉入2)
(這一點只是為了提高儲存效率而要求的,其實理論上沒有也可以,但如果沒有,實際使用時效率會大大降低,所以我們這裡將其做為必需的。後面會重點講到這個問題。)
2),判斷兩個對象用equals運算是否相等
如果不相等,認為兩個對象也不相等
如果相等,認為兩個對象相等(equals()是判斷兩個對象是否相等的關鍵)
我個人感覺上邊的說法是 hashset 判定元素是否重複的規則(因為hashset不允許元素重複)
而非Hashtable、HashMap、HashSet、LinkedHashMap在代碼中調用equals,就可以判斷他們是否相等了
看一下下邊的例子
class Name
{
private String first;
private String last;
public Name(String first, String last)
{
this.first = first;
this.last = last;
}
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o.getClass() == Name.class)
{
Name n = (Name)o;
return n.first.equals(first)
&& n.last.equals(last);
}
return false;
}
}
public class HashSetTest
{
public static void main(String[] args)
{
Set<Name> s = new HashSet<Name>();
s.add(new Name("abc", "123"));
System.out.println(
s.contains(new Name("abc", "123")));
}
}
上面程式中向 HashSet 裡添加了一個 new Name("abc", "123") 對象之後,立即通過程式判斷該 HashSet 是否包含一個 new Name("abc", "123") 對象。粗看上去,很容易以為該程式會輸出 true。
實際運行上面程式將看到程式輸出 false,這是因為 HashSet 判斷兩個對象相等的標準除了要求通過 equals() 方法比較返回 true 之外,還要求兩個對象的hashCode()
傳回值相等。而上面程式沒有重寫 Name 類的 hashCode() 方法,兩個 Name 對象的 hashCode() 傳回值並不相同,因此 HashSet 會把它們當成 2 個對象處理,因此程式返回 false。
由此可見,當我們試圖把某個類的對象當成 HashMap 的 key,或試圖將這個類的對象放入 HashSet 中儲存時,重寫該類的 equals(Object obj) 方法和 hashCode() 方法很重要,而且這兩個方法的傳回值必須保持一致:當該類的兩個的 hashCode() 傳回值相同時,它們通過 equals() 方法比較也應該返回 true。通常來說,所有參與計算 hashCode() 傳回值的關鍵屬性,都應該用於作為 equals()
比較的標準。
如下程式就正確重寫了 Name 類的 hashCode() 和 equals() 方法,程式如下:
Java代碼
class Name
{
private String first;
private String last;
public Name(String first, String last)
{
this.first = first;
this.last = last;
}
// 根據 first 判斷兩個 Name 是否相等
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o.getClass() == Name.class)
{
Name n = (Name)o;
return n.first.equals(first);
}
return false;
}
// 根據 first 計算 Name 對象的 hashCode() 傳回值
public int hashCode()
{
return first.hashCode();
}
public String toString()
{
return "Name[first=" + first + ", last=" + last + "]";
}
}
public class HashSetTest2
{
public static void main(String[] args)
{
HashSet<Name> set = new HashSet<Name>();
set.add(new Name("abc" , "123"));
set.add(new Name("abc" , "456"));
System.out.println(set);
}
}
上面程式中提供了一個 Name 類,該 Name 類重寫了 equals() 和 toString() 兩個方法,這兩個方法都是根據 Name 類的 first 執行個體變數來判斷的,當兩個 Name 對象的 first 執行個體變數相等時,這兩個 Name 對象的 hashCode() 傳回值也相同,通過 equals() 比較也會返回 true。
程式主方法先將第一個 Name 對象添加到 HashSet 中,該 Name 對象的 first 執行個體變數值為"abc",接著程式再次試圖將一個 first 為"abc"的 Name 對象添加到 HashSet 中,很明顯,此時沒法將新的 Name 對象添加到該 HashSet 中,因為此處試圖添加的 Name 對象的 first 也是" abc",HashSet 會判斷此處新增的 Name 對象與原有的 Name 對象相同,因此無法添加進入,程式在①號代碼處輸出 set 集合時將看到該集合裡只包含一個
Name 對象,就是第一個、last 為"123"的 Name 對象。
HashSet 底層採用 HashMap 來儲存所有元素,儲存搭配HashMap的key中,所義HashMap的key判斷key是否相等也是從hashcode和equals是否相等判斷
轉自 http://blog.csdn.net/willielee/article/details/5804463
只有用到Hashtable、HashMap、HashSet、LinkedHashMap等時才要注意hashcode,其他地方hashcode無用。(這麼理解不一定對)
判斷兩個對象是否相等是否要求hashcode() 相等,下邊的說法是否對
在java的集合中,判斷兩個對象是否相等的規則是:
1),判斷兩個對象的hashCode是否相等
如果不相等,認為兩個對象也不相等,完畢
如果相等,轉入2)
(這一點只是為了提高儲存效率而要求的,其實理論上沒有也可以,但如果沒有,實際使用時效率會大大降低,所以我們這裡將其做為必需的。後面會重點講到這個問題。)
2),判斷兩個對象用equals運算是否相等
如果不相等,認為兩個對象也不相等
如果相等,認為兩個對象相等(equals()是判斷兩個對象是否相等的關鍵)
我個人感覺上邊的說法是 hashset 判定元素是否重複的規則(因為hashset不允許元素重複)
而非Hashtable、HashMap、HashSet、LinkedHashMap在代碼中調用equals,就可以判斷他們是否相等了
看一下下邊的例子
class Name
{
private String first;
private String last;
public Name(String first, String last)
{
this.first = first;
this.last = last;
}
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o.getClass() == Name.class)
{
Name n = (Name)o;
return n.first.equals(first)
&& n.last.equals(last);
}
return false;
}
}
public class HashSetTest
{
public static void main(String[] args)
{
Set<Name> s = new HashSet<Name>();
s.add(new Name("abc", "123"));
System.out.println(
s.contains(new Name("abc", "123")));
}
}
上面程式中向 HashSet 裡添加了一個 new Name("abc", "123") 對象之後,立即通過程式判斷該 HashSet 是否包含一個 new Name("abc", "123") 對象。粗看上去,很容易以為該程式會輸出 true。
實際運行上面程式將看到程式輸出 false,這是因為 HashSet 判斷兩個對象相等的標準除了要求通過 equals() 方法比較返回 true 之外,還要求兩個對象的hashCode()
傳回值相等。而上面程式沒有重寫 Name 類的 hashCode() 方法,兩個 Name 對象的 hashCode() 傳回值並不相同,因此 HashSet 會把它們當成 2 個對象處理,因此程式返回 false。
由此可見,當我們試圖把某個類的對象當成 HashMap 的 key,或試圖將這個類的對象放入 HashSet 中儲存時,重寫該類的 equals(Object obj) 方法和 hashCode() 方法很重要,而且這兩個方法的傳回值必須保持一致:當該類的兩個的 hashCode() 傳回值相同時,它們通過 equals() 方法比較也應該返回 true。通常來說,所有參與計算 hashCode() 傳回值的關鍵屬性,都應該用於作為 equals()
比較的標準。
如下程式就正確重寫了 Name 類的 hashCode() 和 equals() 方法,程式如下:
Java代碼
class Name
{
private String first;
private String last;
public Name(String first, String last)
{
this.first = first;
this.last = last;
}
// 根據 first 判斷兩個 Name 是否相等
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o.getClass() == Name.class)
{
Name n = (Name)o;
return n.first.equals(first);
}
return false;
}
// 根據 first 計算 Name 對象的 hashCode() 傳回值
public int hashCode()
{
return first.hashCode();
}
public String toString()
{
return "Name[first=" + first + ", last=" + last + "]";
}
}
public class HashSetTest2
{
public static void main(String[] args)
{
HashSet<Name> set = new HashSet<Name>();
set.add(new Name("abc" , "123"));
set.add(new Name("abc" , "456"));
System.out.println(set);
}
}
上面程式中提供了一個 Name 類,該 Name 類重寫了 equals() 和 toString() 兩個方法,這兩個方法都是根據 Name 類的 first 執行個體變數來判斷的,當兩個 Name 對象的 first 執行個體變數相等時,這兩個 Name 對象的 hashCode() 傳回值也相同,通過 equals() 比較也會返回 true。
程式主方法先將第一個 Name 對象添加到 HashSet 中,該 Name 對象的 first 執行個體變數值為"abc",接著程式再次試圖將一個 first 為"abc"的 Name 對象添加到 HashSet 中,很明顯,此時沒法將新的 Name 對象添加到該 HashSet 中,因為此處試圖添加的 Name 對象的 first 也是" abc",HashSet 會判斷此處新增的 Name 對象與原有的 Name 對象相同,因此無法添加進入,程式在①號代碼處輸出 set 集合時將看到該集合裡只包含一個
Name 對象,就是第一個、last 為"123"的 Name 對象。
HashSet 底層採用 HashMap 來儲存所有元素,儲存搭配HashMap的key中,所義HashMap的key判斷key是否相等也是從hashcode和equals是否相等判斷
轉自 http://blog.csdn.net/willielee/article/details/5804463