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

  • 相关阅读:
    服务器运行jupyter,本地浏览器打开
    转载--对batch normalization的理解
    Deep Neural Networks for YouTube Recommendations YouTube的经典推荐框架
    IFrame与window对象(contentWindow)
    vue之watch的理解
    关于npm
    简单的输入法效果(类似百度输入时候的智能检索)
    Js屏蔽网页复制,不能使用右键菜单,禁止复制网页内容,不能选中内容,右键不让用,无法拖拽选择,这么多功能,用JS一句代码就搞定了
    移动端关于计算rem的flexible.js
    解决安卓手机在input获取焦点时候固定定位元素被输入键盘给顶到顶部
  • 原文地址:https://www.cnblogs.com/CrazyDog/p/3681243.html
Copyright © 2011-2022 走看看