.NET程序员都知道,如果我们重写一个类的Equals方法而没有重写GetHashCode,则VS会提示警告 :“***”重写 Object.Equals(object o)但不重写 Object.GetHashCode() 。

但是,为什么重写Equals一定要同时重写GetHashCode呢?

微软的解释是:

GetHashCode 基于适合哈希算法和诸如哈希表的数据结构的当前实例返回一个值。 两个相等的同类型对象必须返回相同的哈希代码,才能确保以下类型的实例正确运行:

链接:http://msdn.microsoft.com/zh-cn/library/vstudio/ms182358.aspx

举个例子:

重写一个Person类

 public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; } /// <summary>
/// 重写Equals,如果Name与Age相等,就认为类相等
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (obj is Person)
{
var person = obj as Person;
return person.Age == this.Age && person.Name == this.Name;
}
else
return false;
}
}

写一个测试方法:

  public  static void Main(string[] args)
{
Person person1 = new Person() { Id = , Name = "AA", Age = };
Person person2 = new Person() { Id = , Name = "AA", Age = }; Console.WriteLine("person1与person2是否相等:" + person1.Equals(person2));
Console.Read();
}

结果:

返回的结果是true,这好像是我们的重写方法成功了。那我们继续写一个测试方法吧。

            ICollection<Person> list = new HashSet<Person>();
list.Add(person1);
Console.WriteLine("List是否包含person1:"+list.Contains(person1));
Console.WriteLine("List是否包含person2:" + list.Contains(person2));

结果:

这时,就出问题了。既然person1与person2相等,list它包含person1,那也应该包含person2吧。原因就是我们没有重写GetHashCode方法,相同的对象没有返回相等的HashCode。

我们重新改变一下Person,让它重写GetHashCode方法。

 public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; } /// <summary>
/// 重写Equals,如果Name与Age相等,就认为类相等
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (obj is Person)
{
var person = obj as Person;
return person.Age == this.Age && person.Name == this.Name;
}
else
return false;
} public override int GetHashCode()
{
return this.Name.GetHashCode()^this.Age.GetHashCode();
}
}

再运行两个测试方法:

现在,方法都返回true了。

还有一个例子,如果将Person类当作键值放在字典中也会有问题,可以参见:http://book.51cto.com/art/201109/292340.htm

重写GetHashCode的原则很简单,只要能保证两个相等的同类型对象返回相同的哈希代码就OK了。

还找到一个说得比较好的地方,里面第二个评论很精彩。http://blog.csdn.net/chenyuxu0/article/details/5886771

重写Equals为什么要同时重写GetHashCode的更多相关文章

  1. 【转】重写Equals为什么要同时重写GetHashCode

    .NET程序员都知道,如果我们重写一个类的Equals方法而没有重写GetHashCode,则VS会提示警告 :“***”重写 Object.Equals(object o)但不重写 Object.G ...

  2. java -为什么重写equals(),还需要重写hashCode()?

    1.先post这两个方法的基本定义: equals()的定义: 浅谈Java中的equals和==(转) hashCode()的定义: java中hashCode()方法的作用 Java中hashCo ...

  3. 为什么重写equals()方法就必须重写hashCode()方法

    hashCode()和equals()保持一致,如果equals方法返回true,那么两个对象的hasCode()返回值必须一样.如果equals方法返回false,hashcode可以不一样,但是这 ...

  4. 一文搞懂--Java中重写equals方法为什么要重写hashcode方法?

    Java中重写equals方法为什么要重写hashcode方法? 直接看下面的例子: 首先我们只重写equals()方法 public class Test { public static void ...

  5. 为什么重写equals的同时要重写hashcode

    在覆盖equals方法的时候,你必须要遵守它的通用约定.下面是约定的内容,来自Object的规范[JavaSE6] 自反性.对于任何非null的引用值x,x.equals(x)必须返回true. 对称 ...

  6. 重写equals()方法也要重写hashcode()方法

    如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值.

  7. JAVA中重写equals()方法为什么要重写hashcode()方法?

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...

  8. why在重写equals时还必须重写hashcode方法

    首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法 public boolean equals(Object anO ...

  9. 为什么重写equals时一定要重写hashcode

    我们开发时写一个类,默认继承Object类,Object类的equals方法是比较是否指向同一个对象(地址是否相同), Object类 的hashcode方法返回的对象内存地址的值, 一个类只重写了e ...

随机推荐

  1. 2.交通聚类 -层次聚类(agnes)Java实现

    1.项目背景 在做交通路线分析的时候,客户需要找出车辆的行车规律,我们将车辆每天的行车路线当做一个数据样本,总共有365天或是更多,从这些数据中通过聚类来获得行车路线规律统计分析. 我首先想到是K-m ...

  2. DiscuzX 论坛首页 和 分 区设置版块横排

    在论坛看到很多新手站长在咨询怎么样才可以设置和Discuz! 官方论坛首页一个分区下面横排3个板块或者更多呢?如下图: 下面我一起来操作下: 论坛 后台 论坛 板块管理 分区 编辑 图一: 图二: 说 ...

  3. 虚拟机安装Ubuntu三种网络模式

    VMWare提供三种工作模式桥接(bridge).NAT(网络地址转换)和host-only(主机模式). NAT(网络地址转换) 在NAT模式下,虚拟系统需要借助NAT(网络地址转换)功能,通过宿主 ...

  4. saltstack 入门命令

    master服务启动 CentOS 7 (Debian.OpenSuse.Fedora) systemctl start salt-master /etc/init.d/salt-master sta ...

  5. 基于SSL协议的双向认证 - 双向认证 [3]

    1      SSL双向认证的实现 这里是基于SSL和Tomcat配置实现的,配置方法如下: 1.1    生成CA数字证书 首先需要配置OPENSSL环境变量. 我的OPENSSL配置文件路径是“D ...

  6. DP~青蛙过河(hrbust1186)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAxoAAAKlCAYAAABMq5pGAAAgAElEQVR4nOzdf4xl53nY9/mrQP8r+k

  7. iOS开发——项目需求-快速回到当前界面的顶部

    利用UIWindow实现快速到达顶部 如下图,在状态栏添加一个没有颜色的UIWindow(里面添加一个按钮),实现点击这个按钮时能快速的回到当前界面的顶部 核心代码 一.利用UIWindow实现到达顶 ...

  8. Google在三大系统上停止对Chrome Apps的支持

    近年来凭借着低廉的价格和易于管理和追踪的特性,Chrome OS设备逐渐获得了市场的肯定.只是相比较Windows和macOS桌面系统来说,Chrome OS在应用方面依然存在劣势,为此三年前Goog ...

  9. [POJ2109]Power of Cryptography

    [POJ2109]Power of Cryptography 试题描述 Current work in cryptography involves (among other things) large ...

  10. jquery版悬浮模块demo

    在做在线客服时,代码就是按照该模块命名.现在,我要添加一个返回主页的功能,我觉得再复制一遍之前的代码,那个量有点多,如果我再添加一个功能,那个量会很多……现在我用创建对象字面量的方式来创建(其实我还想 ...