如何使用项目的哈希检查HashSet是否包含项目?

时间:2014-08-10 20:42:03

标签: c# hash hashcode hashset

我想检查HashSet是否包含特定元素。我已经有了元素的int哈希码,但没有对元素本身的引用。

是否可以在不迭代整个集合的情况下执行此操作?

2 个答案:

答案 0 :(得分:4)

不,因为

  • 哈希代码与对象(pigeon principle
  • 没有一对一的映射关系
  • .Net HashSet / Dictionary不公开此实施细则

如果你真的需要通过哈希码找到对象,你可以

  • 迭代所有项目并比较哈希码
  • 如果这是主要功能 - 请考虑自定义比较器是否会让您拥有与任何具有相同哈希码的其他对象匹配的特殊对象...

特殊比较器的近似代码

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

近似用法:

var myHashSet = new HashSet<ObjectsToStore>(new ComparerByHashCode());
var itemByHashCode = myHashSet[new ObjectsToStore{HasCodeOverwrite= 1234}];

答案 1 :(得分:0)

没有。散列函数是单向函数。它将实例从(可能无限大的)空间映射到有限的大空间。它加快了流程,但并不能保证唯一性。

日常生活中非常简单的哈希函数可以是:存储员工记录,秘书使用26个文件夹,命名为&#39; A&#39;到&#39; Z&#39;朱丽叶的唱片存放在文件夹&#39; J&#39;,迈克的记录在&#39; M&#39;,查理&#39; C&#39;中。现在我给你这26个文件夹,你想知道公司里是否有人叫奥斯卡。除非&#39; O&#39;文件夹为空,您必须检查该文件夹中的每条记录以告知答案。