How can I check if a HashSet contains an item using the hash of the item?

后端 未结 2 1422
天命终不由人
天命终不由人 2021-01-21 04:30

I want to check if a HashSet contains a specific element. I already have the int hashcode of the element but not a reference to the element itself.

Is it po

相关标签:
2条回答
  • 2021-01-21 05:19

    No. Hash functions are one-way functions. It maps instances from a (potentially infinity large) space to a limited large space. It speeds up process, but doesn't guarantee uniqueness.

    A very simply hash function in daily life can be: to store employee records, the secretary uses 26 folders, named 'A' to 'Z'. Juliet's record is stored in folder 'J', Mike's record in 'M', Charlie's in 'C'. Now I give you these 26 folders, and you want to know whether there is someone called Oscar in the company. Unless the 'O' folder is empty, you'll have to check every record in that folder to tell the answer.

    0 讨论(0)
  • 2021-01-21 05:22

    No, because

    • there is no one-to-one mapping of hash code to object (pigeon principle)
    • .Net HashSet / Dictionary don't expose this implementaion details

    If you really need to find object by hash code you can

    • iterate all items and compare hash code
    • if this is main functionality - consider if custom comparer that will let you have special object that will match any other object with the same hash code will work...

    Approximate code for special comparer

     class ObjectsToStore
     {
         ....
         public int? HashCodeOverwrite; 
     }
    
     class ComparerByHashCode : IEqualityComparer<ObjectsToStore>
     {
    
       public bool Equals(ObjectsToStore b1, ObjectsToStore b2)
       {
           if (b1.HashCodeOverwrite.HasValue || b2.HashCodeOverwrite.HasValue)
           {
               return b1.GetHashCode() == b2.GetHashCode());
           }
           // add all null checks here too.
           return b1.Equals(b2);
       }
    
       public int GetHashCode(ObjectsToStore b)
       {
         return b.HashCodeOverwrite.HasValue? b.HashCodeOverwrite.Value:b.GetHashCode();
       }
     }
    

    Approximate usage:

    var myHashSet = new HashSet<ObjectsToStore>(new ComparerByHashCode());
    var itemByHashCode = myHashSet[new ObjectsToStore{HasCodeOverwrite= 1234}];
    
    0 讨论(0)
提交回复
热议问题