What happens when hash collision happens in Dictionary key?

前端 未结 4 756

I\'ve been coding in c++ and java entirety of my life but on C#, I feel like it\'s a totally different animal.

In case of hash collision in Dictionary container in

相关标签:
4条回答
  • 2020-12-05 03:22

    Check this link for a good explanation: An Extensive Examination of Data Structures Using C# 2.0

    Basically, .NET generic dictionary chains items with the same hash value.

    0 讨论(0)
  • 2020-12-05 03:25

    According to this article at MSDN, in case of a hash collision the Dictionary class converts the bucket into a linked list. The older HashTable class, on the other hand, uses rehashing.

    0 讨论(0)
  • 2020-12-05 03:28

    I offer an alternative code oriented answer that demonstrates a Dictionary will exhibit exception-free and functionally correct behavior when two items with different keys are added but the keys produce the same hashcode.

    On .Net 4.6 the strings "699391" and "1241308" produce the same hashcode. What happens in the following code?

    myDictionary.Add( "699391", "abc" );
    myDictionary.Add( "1241308", "def" );
    

    The following code demonstrates that a .Net Dictionary accepts different keys that cause a hash collision. No exception is thrown and dictionary key lookup returns the expected object.

    var hashes = new Dictionary<int, string>();
    var collisions = new List<string>();
    
    for (int i = 0; ; ++i)
    {
        string st = i.ToString();
        int hash = st.GetHashCode();
    
        if (hashes.TryGetValue( hash, out string collision ))
        {
            // On .Net 4.6 we find "699391" and "1241308".
            collisions.Add( collision );
            collisions.Add( st );
            break;
        }
        else
            hashes.Add( hash, st );
    }
    Debug.Assert( collisions[0] != collisions[1], "Check we have produced two different strings" );
    Debug.Assert( collisions[0].GetHashCode() == collisions[1].GetHashCode(), "Prove we have different strings producing the same hashcode" );
    
    var newDictionary = new Dictionary<string, string>();
    newDictionary.Add( collisions[0], "abc" );
    newDictionary.Add( collisions[1], "def" );
    
    Console.Write( "If we get here without an exception being thrown, it demonstrates a dictionary accepts multiple items with different keys that produce the same hash value." );
    
    Debug.Assert( newDictionary[collisions[0]] == "abc" );
    Debug.Assert( newDictionary[collisions[1]] == "def" );
    
    0 讨论(0)
  • 2020-12-05 03:41

    Hash collisions are correctly handled by Dictionary<> - in that so long as an object implements GetHashCode() and Equals() correctly, the appropriate instance will be returned from the dictionary.

    First, you shouldn't make any assumptions about how Dictionary<> works internally - that's an implementation detail that is likely to change over time. Having said that....

    What you should be concerned with is whether the types you are using for keys implement GetHashCode() and Equals() correctly. The basic rules are that GetHashCode() must return the same value for the lifetime of the object, and that Equals() must return true when two instances represent the same object. Unless you override it, Equals() uses reference equality - which means it only returns true if two objects are actually the same instance. You may override how Equals() works, but then you must ensure that two objects that are 'equal' also produce the same hash code.

    From a performance standpoint, you may also want to provide an implementation of GetHashCode() that generates a good spread of values to reduce the frequency of hashcode collision. The primarily downside of hashcode collisions, is that it reduces the dictionary into a list in terms of performance. Whenever two different object instances yield the same hash code, they are stored in the same internal bucket of the dictionary. The result of this, is that a linear scan must be performed, calling Equals() on each instance until a match is found.

    0 讨论(0)
提交回复
热议问题