HashCode与IEqualityComparer接口

HashCode对于我这种菜鸟来说,听过,见过,但是具体是干什么的,我不知道。问度娘,看着大家五花八门的解释,我蛋疼了,于是今天有空闲就研究下这玩意,看看这玩意到低是干什么的。 在Msdn上对于Hashcode是这样:用作特定类型的哈希函数。这句话不得不说很抽象,不过还好有备注:GetHashCode方法的默认实现不保证针对不同的对象返回唯一值。 而且,.NET Framework 不保证 GetHashCode 方法的默认实现以及它所返回的值在不同版本的 .NET Framework 中是相同的。 因此,在进行哈希运算时,该方法的默认实现不得用作唯一对象标识符。

好吧,不扯这些理论东西了,大家没事可以去MSDN看看这个东西,我们用代码验证下这玩意。

1,值类型的HashCode分析:

class Program
    {
       static void Main(string[] args)
       {
           int hashCodeA = 0;
           int hashCodeB = 0;
           Console.WriteLine("hashCodeA的值和hashCodeB的值相等的情况Hashcode值分别是");
           Console.WriteLine(hashCodeA.GetHashCode()+"::::"+hashCodeB.GetHashCode());
           hashCodeB = 1;
           Console.WriteLine("hashCodeA的值和hashCodeB的值不相等的情况Hashcode值分别是");
           Console.WriteLine(hashCodeA.GetHashCode() + "::::" + hashCodeB.GetHashCode());
       }
   }

运行的结果:

LC1YWB}5S`)VE[]~3)R@E6Q

来,小伙伴们,我们来看第二值类型:关于Struct的

public struct StructHashCode//定义一个结构体
   {
     public int a;
    public int b;
   }

class Program
   {
       static void Main(string[] args)
       {
           StructHashCode sCode1 = new StructHashCode();
           sCode1.a = 1;
           sCode1.b = 1;
           StructHashCode sCode2 = new StructHashCode();
           sCode2.a = 1;
           sCode2.b = 1;
           if (sCode1.GetHashCode() == sCode2.GetHashCode())
               Console.WriteLine("我们是相等的哦,亲");
           else
               Console.WriteLine("我们是不想等的哦,亲");
           Console.WriteLine("********华丽分割线***********");
           sCode2.a = 1;
           sCode2.b = 2;
           if (sCode1.GetHashCode() == sCode2.GetHashCode())
               Console.WriteLine("我们是相等的哦,亲");
           else
               Console.WriteLine("我们是不想等的哦,亲");
           Console.WriteLine("********华丽分割线***********");
           sCode2.a = 2;
           sCode2.b = 2;
           if (sCode1.GetHashCode() == sCode2.GetHashCode())
               Console.WriteLine("我们是相等的哦,亲");
           else
               Console.WriteLine("我们是不想等的哦,亲");
         
       }

   }

运行结果:(看到这个结果我想骂娘了)

T7WA6S~8ST5K~AGCUVRT[Q5

这两个关于值类性的例子大家是不是有种困惑的感觉,很抱歉的是,我也不能给大家解释这是为什么,但是我们最起码验证了:HashCode看来是个栈地址是没什么关系的。希望有大拿帮我解惑。

2,引用类型的HashCode分析:

class Program
   {
       static void Main(string[] args)
       {
           ClassHashCode classCode1 = new ClassHashCode();
           ClassHashCode classCode2 = new ClassHashCode();
           ClassHashCode classCode3 = classCode1;
           Console.WriteLine("classCode1和classCode2的HashCode进行比较");
           if (classCode1.GetHashCode() == classCode2.GetHashCode())
               Console.WriteLine("我们是相等的哦,亲");
           else
               Console.WriteLine("我们是不想等的哦,亲");
           Console.WriteLine("******华丽的分割线******");
           Console.WriteLine("classCode1和classCode3的HashCode进行比较");
           if (classCode1.GetHashCode() == classCode3.GetHashCode())
               Console.WriteLine("我们是相等的哦,亲");
           else
               Console.WriteLine("我们是不想等的哦,亲");

}

}
   public class ClassHashCode
   {

}

运行的结果:

KPA2%W__%V%(QQ8[HG4IWKT

那么关于classCode1 和classCode2和classCode3之间的关于堆和栈的那点区别,在这我就本给大家叙述了,不懂可以问问度娘。

到这里我想就可以做个总结了:无论是值类型还是引用类型,最终来说都是Object对象,那么对象与对象之间如果相等,HashCode一定是一样的,如果不想等,HashCode也不一定不一样(因为有值类型这样的怪东西)。事情发展到这里大家就多少明白点了吧,HashCode有太多不确定的。以上是个人观点,希望大拿指正。。

上文提到classCode1和classCode2是不想等的,但是如果我们忽略HashCode不相等(堆和栈的引用地址不等,这时候看来,HashCode好像也和地址有关联),那么我就可以认为他们是相等的了,大家是不是就想到对象的重复的筛选。

IEqualityComparer<T>就出现啦,他的具体含义大家可以看看MSDN哦 ,具体代码实现:

class Program
{
     static void Main(string[] args)
     {
         UserComparer userComparer = new UserComparer();
         People people1 = new People(1, "huhu");
         People people2 = new People(1, "huhu");
         People people3 = new People(2, "lala");
         People people4 = new People(2, "lala");
         People people5 = new People(3, "gaga");
         People people6 = new People(3, "gaga");
         People people7 = new People(4, "momo");
         List<People> peopleList = new List<People>();
         peopleList.Add(people1);
         peopleList.Add(people2);
         peopleList.Add(people3);
         peopleList.Add(people4);
         peopleList.Add(people5);
         peopleList.Add(people6);
         peopleList.Add(people7);
       
         var newPeopleList = peopleList.Distinct(userComparer);
         foreach (var item in newPeopleList)
         {
            
             Console.WriteLine(item.ID + "::::" + item.Name);
         }
        
     }

}
/// <summary>
/// 定义people的类
/// </summary>
public class People
{
     public int ID { get; set; }
     public string Name { get; set; }
     public People(int id, string name)
     {
         ID = id;
         Name = name;
     }

}
/// <summary>
/// 实现IEqualityComparer的接口对于类型 pepple,您可以创建自己的相等定义
/// </summary>
public class UserComparer : IEqualityComparer<People>
{
     /// <summary>
     /// 自己定义people对象的相等的规则
     /// </summary>
     /// <param name="x"></param>
     /// <param name="y"></param>
     /// <returns></returns>
     public bool Equals(People x, People y)
     {
         if (x.ID == y.ID && x.Name == y.Name)
             return true;
         else
             return false;
     }
     /// <summary>
     /// 自己定义peopel的Hashcode的返回规则,我这里关于people这个对象的hashcode都是0(为了省事)
     /// </summary>
     /// <param name="obj"></param>
     /// <returns></returns>
     public int GetHashCode(People obj)
     {
         return 0;
     }


}

运行的结果的:

WF8N7OLB]8N{S(X0Z2LN7VN

通过以上验证,我个人认为,对象之间的相等和HashCode有这藕断丝连的感觉,但是对这个HashCode还是感觉有种意犹未尽,想伸进去,但是又找不到门路的感觉,喜欢能抛砖引玉,引来大拿为我解惑。。。

posted on 2014-04-22 19:04  楼主的跟屁虫  阅读(279)  评论(0)    收藏  举报