zoukankan      html  css  js  c++  java
  • 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还是感觉有种意犹未尽,想伸进去,但是又找不到门路的感觉,喜欢能抛砖引玉,引来大拿为我解惑。。。

  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/CrazyDog/p/3681243.html
Copyright © 2011-2022 走看看