2012-08-30 48 views
-4
對象

如果我有引用類型的對象,我創建了兩個對象具有相同屬性 將它們有相同的哈希碼?將哈希碼給我相同的結果爲具有相同屬性

示例類:

class Person 
{ 
    int id; 
    string name; 

    public Person(int pid, string pname) 
    { 
     this.id = pid; 
     this.name = pname; 
    } 
} 

然後定義兩個對象:

Person p1 = new Person(1,"xxx"); 
Perdon p2 = new Person(1,"xxx"); 

//p1.GetHashCode()= p2.GetHashCode()?

編輯:我想這個代碼,並得到了不同的充的結果,但對字符串測試的東西給了我同樣的結果
我爲什麼要問

+6

你運行過嗎?結果是什麼?測試你自己的時間比在這裏問的要少得多。 – Oded

+0

您不希望它們具有相同的哈希碼。 –

+0

@已付給你的權利,但我試圖在sa字符串上,我得到了相同的結果,然後在這個類上嘗試它,並得到了相同的rsult,令人困惑 – Star

回答

1

你是對自己負責執行GetHashCode。如果你不這樣做,他們將不會有相同的散列碼,儘管他們應該。

+1

「雖然他們應該」 - 我認爲他們不應該。 Person是一個可變參考類型。 –

+0

@HenkHolterman:我在這裏看不到任何可變性。 –

+0

@亨克是對的 - 這些字段沒有被聲明爲'readonly',所以可以被突變。 – Oded

1

如果人是一個結構,則哈希碼將被從成員值中生成,你會得到相同的結果。但是,對於類,默認的哈希碼實現將根據其內存引用爲每個對象提供唯一的哈希碼。

因此,在這種情況下,如果你想爲P1和P2相同的哈希碼,你必須提供自己的實現。

+2

也許應該補充一點,他們*應該*確實不會得到相同的哈希代碼,因爲如果哈希代碼不相同(爲了使哈希符合它們的目的)提供相等的良好指示),並且如果p1和p2是類類型,則p1.Equals(p2)== false,因爲類類型的相等的默認概念是對象標識。 – JohnB

+1

如果它是一個結構體,我建議給它添加一個'GetHashCode()'。爲結構生成合理的默認哈希碼的代碼非常聰明,但令人遺憾的是,巧妙有點沉重。 –

0

默認情況下,他們不會(爲引用類型)。你可以試試看看。

如果你希望他們有相同的哈希碼,你必須()相應編寫自己的GetHashCode。

1

在這裏看到的默認實現: http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

GetHashCode方法的默認實現不保證唯一的返回值不同的對象。此外,.NET Framework不保證GetHashCode方法的默認實現,並且它返回的值在不同版本的.NET Framework之間將保持不變。因此,此方法的默認實現不能用作用於散列目的的唯一對象標識符。

但我覺得你真的想知道的是哈希碼是如何工作的。

比方說,你有下面的類:

public Person 
{ 
    private string name; 
    public Person(Name name) 
    { 
     this.name = name; 
    } 
} 

現在,讓我們說你要比較兩個人,檢查他們是否有相同的名字,你是怎麼做到這一點?您重寫在Object中實現的等於。 (在C#中的所有類繼承對象隱含的) 像這樣:

public Person 
{ 
    private string name; 
    public Person(Name name) 
    { 
     this.name = name; 
    } 

    public override bool Equals(Object obj) 
    { 
     if(obj == null) 
      return false // not equal if obj is null 

     Equals temp = obj as Equals; // temp set to null if obj can not be cast to equals 
     if(p == null) 
      return false 

     // if code gets here, the code object passed is an instance of Equals. 
     // Now we have to check if the strings match. 
     bool isEqual = p.name == this.name; // set if the two names match 
     return isEqual; // return if these two match 
    } 
} 

所以,現在,你可以檢查,如果兩個人都是平等的。 例子:

Person p1 = new Person("Jack"); 
Person p2 = new Person("Jack"); 
Person p3 = new Person("Jill"); 
Object p4 = new Person("Jill"); 

p1.Equals(p2) // returns true 
p1.Equals(p3) // returns false 
p4.Equals(p1) // returns false 
p4.Equals(p3) // returns true 

現在,讓我們說你有一個巨大的人一樣,一百萬的列表,你想知道,如果命名"amy"的人在這個列表中存在。你如何找到這個人?你會一個一個地循環所有的名字,並檢查這個人是否等於艾米?但是這樣會很慢,如果艾米是這個名單中的第100萬人呢?我們如何提高性能?

輸入哈希碼。

讓我們假設你寫一個簡單的哈希碼算法: 哈希碼是人名中每個字母的每個數字的總和。

public Person 
{ 
    private string name; 
    public Person(Name name) 
    { 
     this.name = name; 
    } 

    public override bool Equals(Object obj) 
    { 
     if(obj == null) 
      return false // not equal if obj is null 

     Equals temp = obj as Equals; // temp set to null if obj can not be cast to equals 
     if(p == null) 
      return false 

     // if code gets here, the code object passed is an instance of Equals. 
     // Now we have to check if the strings match. 
     bool isEqual = p.name == this.name; // set if the two names match 
     return isEqual; // return if these two match 
    } 

    public override int GetHashCode() 
    { 
     int sum = 0; 
     foreach(char c in this.name) 
     { 
      sum += c; 
     } 
     return sum; 
    } 
} 

因此,如果我們有amy她的哈希碼會1 + 13 + 25,所以38

現在不是一個普通的列表,而是有一個名爲「桶」的列表。你的散列碼決定你去哪個桶。 amy has hascode如果38她去桶38

現在讓我們說我們有另外一個人,名字may,她有她的名字相同的字母,所以她的哈希碼也38,她也進入水桶現在38

,只要你想,以檢查是否艾米存在在這個列表中。我們首先檢查她的哈希碼,其中38,現在我們去查看桶38,並且循環遍歷桶38中的所有對象,我們檢查桶38中的任何對象是否匹配amy,如果爲true,則返回true,如果爲false,則返回false 。所以如果你有一百萬人,那麼你必須做的檢查清單才能知道amy是否存在於這個清單中,這個清單會大大減少。

所以基本上,如果你要使用的哈希碼你得遵守以下規則:

  • 您必須覆蓋&實現equals如果你要使用的哈希碼。
  • 的兩個對象,其中的Equals返回true,就必須有相同的hashCode
  • 兩個對象是不同的可能具有相同的哈希碼,但不一定必須是相同的。

這基本上就是它的要義。

+0

很長的答案,但它並沒有真正關注核心問題:什麼是默認行爲。 –

+0

@HenkHolterman我想你是對的,但我嘗試t_t。 *編輯答案*。但我想我回答了他想問的問題,因爲他的問題看起來好像他不知道什麼是哈希碼。 – ProgrammerAtWork

相關問題