2010-11-15 63 views
2

我想了解如何在散列表中使用鍵排序/插入檢查。 我已經瞭解到,當我將一個對象添加到散列表時,它會在運行時檢查那裏是否已經輸入了相同的密鑰。在HashTable中插入兩次相同的密鑰,這怎麼可能?

在我的測試,我已經2個哈希表的鍵與填充: 1-整數 2 - 我已經重寫的對象GetHashCode方法回到這裏總是1.

我的問題:當第一個測試在添加相同的int鍵時打破,第二個測試不是!怎麼來的?在插入時應檢查的哈希碼全部返回1.

提前致謝!


我的代碼:

class Collections 
{ 
    public Collections() 
    { 
     // Testing a hashtable with integer keys 
     Dictionary<int, string> d1 = new Dictionary<int, string>(); 
     d1.Add(1, "one"); 
     d1.Add(2, "two"); 
     d1.Add(3, "three"); 
     // d1.Add(3, "three"); // Cannot add the same key, i.e. same hashcode 
     foreach (int key in d1.Keys) 
      Console.WriteLine(key); 

     // Testing a hashtable with objects returning only 1 as hashcode for its keys 
     Dictionary<Hashkey, string> d2 = new Dictionary<Hashkey, string>(); 
     d2.Add(new Hashkey(1), "one"); 
     d2.Add(new Hashkey(2), "two"); 
     d2.Add(new Hashkey(3), "three"); 
     d2.Add(new Hashkey(3), "three"); 
     for (int i = 0; i < d2.Count; i++) 
      Console.WriteLine(d2.Keys.ElementAt(i).ToString()); 

    } 


} 

/// <summary> 
/// Creating a class that is serving as a key of a hasf table, overring the GetHashcode() of System.Object 
/// </summary> 
class Hashkey 
{ 
    public int Key { get; set; } 

    public Hashkey(int key) 
    { 
     this.Key = key; 
    } 

    // Overriding the Hashcode to return always 1 
    public override int GetHashCode() 
    { 
     return 1; 
     // return base.GetHashCode(); 
    } 

    // No override 
    public override bool Equals(object obj) 
    { 
     return base.Equals(obj); 
    } 

    // returning the name of the object 
    public override string ToString() 
    { 
     return this.Key.ToString(); 
    }   
} 

}

回答

4

Dictionary將檢查的哈希碼對象平等。該散列僅用於提出「第一近似」以非常有效地找到相等密鑰可能

您的覆蓋Equals只是委託給基礎實現,它使用引用等式。這意味着HashKey的任何兩個不同實例都不相等,即使它們具有Key屬性的相同值。

你究竟在努力實現什麼?或者你只是想了解GetHashCodeEquals如何相互關聯?

+0

謝謝大家對你的答案。 – Goul 2010-11-15 13:17:53

+0

謝謝大家的回答。我只是想了解如何管理哈希表中的獨特插入。我認爲這只是基於哈希碼而不是對象相等。我更新了我的代碼,只是簡單地從Equal()返回true來進行快速測試,並得到了我正在等待的錯誤:「具有相同密鑰的項目已被添加。」乾杯 – Goul 2010-11-15 13:23:43

3

哈希碼僅僅是一個啓發式的選擇正確的桶來存儲項目。只是因爲2項共享相同的哈希碼並不意味着它們是平等的。在發生衝突的情況下(與您的1哈希代碼一起發生),我們恢復爲在桶內進行簡單搜索,以查找與搜索鍵相等的成員。由於您的平等測試正在檢查引用是否相同,因此不會有任何兩項相等。

1

Equals比較HashKey的參考。

因爲這是不同的實例,它們是不相等的。

Equals應該是這樣的:

public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(this, obj)) 
      return true; 

     var other = obj as Hashkey; 

     return 
      other != null && 
      Key.Equals(other.Key); 
    } 
相關問題