在哈希表中插入两次相同的键,这怎么可能?

发布于 2024-10-02 07:08:58 字数 1819 浏览 0 评论 0原文

我试图了解哈希表中的键排序/插入检查是如何工作的。 我知道,当我将对象添加到哈希表时,它会在运行时检查是否已在其中输入相同的密钥。

在我的测试中,我有 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();
    }        
}

}

I am trying to understand how works the key sorting / insertion check in a hashtable.
I've understood that when I'm adding an object to a hashtable, it checks at runtime that there isn't the same key already entered in there.

In my test, I've 2 hashtables which keys are filled in with:
1- Integers
2- An object which I've overriden the GetHashCode method to return always 1.

My issue here: while the first test is breaking when adding the same int key, the second test isn't! How come? The hashcodes that should be checked at the insertion are all returning 1.

Thank you in advance!


My code:

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();
    }        
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

当爱已成负担 2024-10-09 07:08:58

Dictionary 将检查哈希码对象是否相等。哈希仅用于得出“第一近似值”,以非常有效地找到可能相等的键。

您对 Equals 的重写只是委托给使用引用相等的基本实现。这意味着 HashKey 的任何两个不同实例都是不相等的,即使它们的 Key 属性值相同。

你到底想达到什么目的?或者您只是想了解 GetHashCodeEquals 之间的关系?

Dictionary will check for the hash code and object equality. The hash is just used to come up with a "first approximation" to find possibly equal keys very efficiently.

Your override of Equals just delegates to the base implementation, which uses reference equality. That means any two distinct instances of HashKey are unequal, even if they have the same value for the Key property.

What are you actually trying to achieve? Or are you just trying to understand how GetHashCode and Equals relate to each other?

橪书 2024-10-09 07:08:58

哈希码只是一种启发式方法,用于选择正确的存储桶来存储项目。仅仅因为 2 个项目共享相同的哈希码并不意味着它们相等。在发生冲突的情况下(正如您的 1 哈希码所发生的那样),我们将恢复到存储桶内的简单搜索,以查找等于搜索键的成员。由于相等性测试正在检查引用是否相同,因此没有两个项目会相等。

The hash code is merely an heuristic to choose the right bucket to store the item in. Just because 2 items share the same hashcode doesn't mean that they are equal. In the case of collision (as will be occurring with your 1 hashcode), we revert to simple search within the bucket to find members that are equal to the searched key. As your equality test is checking if the references are the same, no 2 items will ever be equal.

明天过后 2024-10-09 07:08:58

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);
    }

The Equals compares the reference of the HashKey.

Because that are different instances, they are not equal.

Your Equals should look like this:

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

        var other = obj as Hashkey;

        return
            other != null &&
            Key.Equals(other.Key);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文