碰撞是什么

huangapple go评论74阅读模式
英文:

What is the collision

问题

I've been cracking my head for a couple of hours and still don't get what exactly is collision?

Is it when the two different objects are getting identical hash code?
Or is it when two different objects are getting into the same bucket(place) in array of dictionary?

Or is it something else?

static Dictionary<Number, string> dict = new Dictionary<Number, string>();

class Number
{
private int X;

public Number(int x)
{
    X = x;
}

public override bool Equals(object obj)
{
    Number other = obj as Number;
    return X.Equals(other.X);
}

public override int GetHashCode()
{
    return X;
}

}

public static void Main(string[] args)
{
dict.Add(new Number(5), "Value5");
dict.Add(new Number(2), "Value2");
dict.Add(new Number(5), "Value52");
}

Why isn't chaining working here?

英文:

I've been cracking my head for a couple of hours and still don't get what exactly is collision?

Is it when the two different objects are getting identical hash code?
Or is it when two different objects are getting into the same bucket(place) in array of dictionary?

Or is it something else?

static Dictionary&lt;Number, string&gt; dict = new Dictionary&lt;Number, string&gt;();

class Number
{
    private int X;

    public Number(int x)
    {
        X = x;
    }

    public override bool Equals(object obj)
    {
        Number other = obj as Number;
        return X.Equals(other.X);
    }

    public override int GetHashCode()
    {
        return X;
    }
}

public static void Main(string[] args)
{
    dict.Add(new Number(5), &quot;Value5&quot;);
    dict.Add(new Number(2), &quot;Value2&quot;);
    dict.Add(new Number(5), &quot;Value52&quot;);
}

Why isn't chaining working here?

答案1

得分: 4

A hashcode collision is when two different objects get the same hashcode. But that's fine. Hashcodes must be equal when Equals returns true, but it's ok if Equals returns false even if GetHashCode returns the same value(collision case). Furthermore, when two hashcodes are different, then the objects can't be equal, so Equals must return false. That's all about the rules.

But for performance reasons they should be well-distributed, so avoid too many (false) collisions.

In your sample you get an ArgumentException because you add two Numbers with X=5 which is the only property checked in GetHashCode and Equals. You can't add duplicate keys to a dictionary.

You can chain multiple calls only if the method returns the instance that you have modified, so in this case the dictionary. But Add is a void method, so it returns nothing.

But alternatively you can use the collection initializer:

static Dictionary<Number, string> dict = new Dictionary<Number, string>()
{
    { new Number(5), "Value5" }, { new Number(2), "Value2" }, { new Number(5), "Value52" }
};

Of course, this causes the same exception because you add two identical keys.

英文:

> still don't get what exactly is collision? Is it when the two different objects are getting identical hash code? Or is it when two different objects are getting into the same bucket(place) in array of Dictionary?

A hashcode collision is when two different objects get the same hashcode. But that's fine. Hashcodes must be equal when Equals returns true, but it's ok if Equals returns false even if GetHashCode returns the same value(collision case). Furthermore, when two hashcodes are different, then the objects can't be equal, so Equals must return false. That's all about the rules.

But for performance reasons they should be well-distributed, so avoid too many (false) collisions.

In your sample you get an ArgumentException because you add two Numbers with X=5 which is the only property checked in GetHashCode and Equals. You can't add duplicate keys to a dictonary.

> Why isn't chaining working here?

You can chain multiple calls only if the method returns the instance that you have modified, so in this case the dictionary. But Add is a void method, so it returns nothing.

But alternatively you can use the collection initializer:

static Dictionary&lt;Number, string&gt; dict = new Dictionary&lt;Number, string&gt;()
{
    { new Number(5), &quot;Value5&quot; }, { new Number(2), &quot;Value2&quot; }, { new Number(5), &quot;Value52&quot; }
};

Of course this causes the same exception because you add two identical keys.

答案2

得分: 1

Chaining doesn't work because the Add method returns void. It should have been designed to return an instance of the dictionary itself for the chaining to work. I also think this would have been useful.

英文:

Chaining doesn't work because the Add method returns void. It should have been designed to return an instance of the dictionary itself for the chaining to work. I also think this would have been useful.

huangapple
  • 本文由 发表于 2023年5月14日 16:27:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76246535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定