zoukankan      html  css  js  c++  java
  • c#中的equal和getHashCode

    C#中的Equals和getHashCode

    Equals 的基本用法,我就不说,这里我们来看看getHashCode

    hashCode主要用在hashtable类的。是为了快速的验证两个对象是否相等。

    如果两个对象的hashcode不等,这两个对象就不等,

    如果hashcode相等,再进一步比较equals方法。

    有什好处:因为hashcode是int,比较它们是否相等速度非常快,可以提高性能。

    理解一:我们先看看,GetHashCode 在对基于hashcode的集合(hashtable 和 dictionary) 基于key、value的集合的影响;

        public class Person
        {
            public int ID { get; set; }
    
            public string Name { get; set; }
    
            public override bool Equals(object obj)
            {
                if(obj==null || GetType() != obj.GetType())
                {
                    return false;
                }
                return this.ID == (obj as Person).ID;
            }
    
            public override int GetHashCode()
            {
                int hashCode=(this.ID==0 || this.ID==null)?0:this.ID.GetHashCode();
                return hashCode;
            }
        }
    
        class Program
        {
    
            static void Main(string[] args)
            {
    
                //dictionary 和 hastable 是基于hascdoe的 key的; hashcode 必须是唯一的,不重复的额
    
                IDictionary<Person, Object> dic = new Dictionary<Person, Object>();
                var p1 = new Person() { ID = 1, Name = "jack" };
                var p2 = new Person() { ID = 2, Name = "tom" };
                var p3 = new Person() { ID = 2, Name = "tom" };
                
                dic.Add(p1, "1");
                dic.Add(p2, "2");
                dic.Add(p3, "3");
    
                Console.WriteLine(p2.Equals(p3));   //如果仅仅是重写我们的equals的话,我们的p2 和p3 将白视作相等的对象;
    
                //然后他们的hashcode 却不是相等的;
               //而且我们的额每次运行,都会得到不同的值;
                Console.WriteLine(p2.GetHashCode());
                Console.WriteLine(p3.GetHashCode());
                Console.WriteLine("contains");
    
                if (dic.ContainsKey(p3))
                {
                    //如果仅仅是重写我们的euqals的话,在被添加到我们的基于key的hashtable 中
                    //就会出现重复(严格意义上,说是我们的对象值,但引用不同,因为都是通过new 出来的不同对象),违反我hashtable的 不可重复性
                    Console.WriteLine("contains");
                }
                else
                {
                    //所以要保证hashtable的完整性,我们这里就要重写gethashCode()
                    //我们把判断重复的基准定义为我们的额id,当然也可以多个
                    Console.WriteLine("no");
                    //ps 如果你重写gethashcode,你走不到这一步来就报错:已添加了具有相同键的项。
                }

    理解二:

    尽量用最快的时间对对象进行初步判断

    public class Person
        {
            public int Id { get; set; }
    
            public Person(int i)
            {
                Id = i;
            }
            public override bool Equals(object obj)
            {
                Console.WriteLine("call Equals");
                if (obj == null || GetType() != obj.GetType())
                {
                    return false;
                }
                return Id == (obj as Person).Id;
            }
    
            public override int GetHashCode()
            {
                Console.WriteLine("call GetHashCode");
                return Id % 2;
    
            }
        }
    
            class Program
            {
                static void Main(string[] args)
                {
                var p1 = new Person(1);
                var p2 = new Person(2);
                var p3 = new Person(3);
    
                var dic = new Dictionary<Person, object>();
                dic.Add(p1,1);
                Console.WriteLine("----------------");
                dic.ContainsKey(p1);
                Console.WriteLine("----------------");
                dic.ContainsKey(p2);
    
                Console.ReadLine();
    
    
            }
    
           }

     执行结果:

     正如我们所料的,先调用getHashCode,如果,hashCode相等,就会接着掉我们的equals 来判断,自定义对象是否相等;

    当GetHashCode可以直接分辨出不相等时,Equals就没必要调用了,而当GetHashCode返回相同结果时,Equals方法会 被调用从而确保判断对象是否真的相等。所以,

    还是那句话:GetHashCode没必要一定把对象分辨得很清楚(况且它也不可能,一个int不可能代表所 有的可能出现的值),有Equals在后面做保障。GetHashCode仅需要对对象进行快速判断。GetHashCode没必要一定把对象分辨得很清楚

    (况且它也不可能,一个int不可能代表所 有的可能出现的值)

    实例说话:

    .... 未完待续;

    这里补充一个好文章:

    http://blog.jobbole.com/90593/

    关于hascode的建议:

    http://book.51cto.com/art/201109/292340.htm

    对等比较:

    http://www.cnblogs.com/souliid/p/5718968.html

    http://blog.csdn.net/lan_liang/article/details/50234439

  • 相关阅读:
    【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)
    【 js 基础 】【读书笔记】作用域和闭包
    【 js 基础 】【 源码学习 】 setTimeout(fn, 0) 的作用
    入职一个月快速熟悉大型Vue项目经验感想
    Git 实习一个月恍然大悟合集
    不断更新:整理常见的闭包问题
    (转)当margin-top、padding-top的值为百分比时是如何计算的?
    2019年8月面试腾讯前端开发实习生记录
    vue-cli2.X中引入高德地图,将其设为全局对象
    学习整理:用webpack4.x构建基本项目
  • 原文地址:https://www.cnblogs.com/mc67/p/7278101.html
Copyright © 2011-2022 走看看