咨询区

  • David Basarab

直入主题,参考如下代码:


public class Foo
{public int FooId { get; set; }public string FooName { get; set; }public override bool Equals(object obj){Foo fooItem = obj as Foo;if (fooItem == null) {return false;}return fooItem.FooId == this.FooId;}public override int GetHashCode(){// Which is preferred?return base.GetHashCode();//return this.FooId.GetHashCode();}
}

这里的 Foo 表示 table 中的 row,请问在重写 GetHashCode() 方法时我该用哪一种实现呢?

  • base.GetHashCode();

  • this.FooId.GetHashCode();

回答区

  • Marc Gravell

如果你的 item 要作为 DictionaryHashSet 中的key时,那重写 GetHashCode() 简直就是刚需,因为集合会根据 item 的 hashcode 对 item 进行分组,如果两个 item 的 hashcode 不一样,那么 equals 将永远不会被调用,GetHashCode() 方法应该要体现 Equals 的逻辑,比较方式大概如下:

  • 如果 Equals 判定为相等,那么 GetHashCode 必须相等。

  • 如果 GetHashCode 判定为相等,那么 Equals 不一定相等。

再回到你的场景,用 return FooId 来作为 GetHashCode() 的实现是合理的。

不过作为一般场景,当 item 中有多个属性,推荐的做法是组合多个属性,代码如下:


unchecked // only needed if you're compiling with arithmetic checks enabled
{ // (the default compiler behaviour is *disabled*, so most folks won't need this)int hash = 13;hash = (hash * 7) + field1.GetHashCode();hash = (hash * 7) + field2.GetHashCode();...return hash;
}

值得一提是,上面的 hashcode 实现也解决了一个经典的 对角线冲突 问题,比如说:new Foo(3,5) != new Foo(5,3)

再提一点,作为 .NET 程序的惯用习惯,推荐再重写一下 ==!= 操作符。

点评区

这个问题其实非常经典, EqualsGetHashCode 到底是什么关系呢?

我个人认为:在复杂类型的比较中, GetHashCode 永远是一等公民,Equals 才是二等公民,先判断 HashCode 是否一致,在不一致的情况下再看 Equals 是否一致?最终判断对象是否相等。

还有一点值得注意的是,GetHashCode 的实现一定要高效,完成理论上的 O(1) 复杂度,否则在 HashSet,Dictioanry 场景下会死的很惨,参考 HashSet 的 Contains 。

原文链接:https://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overridden?rq=1

NET问答: 重写了 Equals,还有必要重写 GetHashCode 吗?相关推荐

  1. float foo=42e1为什么错_为什么重写了equals()也要重写hashCode()

    小Hub领读: 虽然是很基础的一篇文章,但是对于equals.hashcode两个方法,相信很多人都与其中的规则不熟悉,来跟着小Hub花个8分钟回顾一下! 作者:不学无数的程序员 https://my ...

  2. 为什么重写equals时必须重写hashCode方法?

    2019独角兽企业重金招聘Python工程师标准>>> 首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashco ...

  3. Java的重写equals但不重写hashCode方法的影响

    首先,说下equals和hashCode的关系.JDK API中关于Object类的equals和hashCode方法中说过,总结起来就是两句话:equals相等的两个对象的hashCode也一定相等 ...

  4. 为什么重写equals方法必须重写hashcode方法

    想要知道这个问题,首先需要知道hashcode它的作用: HashCode的作用: 首先来看HashCode的作用,当把对象加入HashSet中时,HashSet会先计算对象的hashcode值来判断 ...

  5. java 为什么重写equals一定要重写hashcode?

    前言 最近复习,又看到了这个问题,在此记录和整理,通过例子来说明这种情况的原因,使大家可以清晰明白这个问题. 初步探索 首先我们要了解equals方法是什么,hashcode方法是什么. equals ...

  6. 为什么重写equals一定要重写hashCode方法?

    大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 下面我们看下Objec ...

  7. 重写equals就必须重写hashCode的原理分析

    因为最近在整理Java集合的源码, 所以今天再来谈谈这个古老的话题,因为后面讲HashMap会用到这个知识点, 所以重新梳理下. 如果不被重写(原生Object)的hashCode和equals是什么 ...

  8. Java实现二树杈_HashSet的hashCode方法和equals方法的重写,TreeSet中compareTo方法的重写,Comparator在treeSet中的应用。...

    HashSet的hashCode方法和equals方法的重写,TreeSet中compareTo方法的重写,Comparator在treeSet中的应用. HashSet: 首先,hashset底层是 ...

  9. java equals重写原则_java中为何重写equals时必须重写hashCode方法详解

    前言 大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 在上一篇博文Ja ...

  10. java重写面试题_Java面试题:重写了equals方法,为什么还要重写hashCode方法?

    核心问题:重写了equals方法,为什么还要重写hashCode方法? 这不仅仅是一道面试题,而且是关系到我们的代码是否健壮和正确的问题.在前面两篇文章涉及到了equals方法的底层讲解:<说说 ...

最新文章

  1. 一起学spring--依赖注入---简单粗暴的例子展示
  2. #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined解释
  3. 1100 Mars Numbers (20 分)【难度: 一般 / 知识点: 模拟】
  4. 【Linux】一步一步学Linux——whereis命令(15)
  5. 微信开放平台全网发布时,检测失败 —— C#
  6. 台阶问题练习题 (简单的dp)
  7. SpringMVC 文件上传
  8. vba 判断是否为数字
  9. T05 FX 试打报告
  10. OpenStack Trove2
  11. 搭建高可用 RocketMQ 集群
  12. Nginx源码分析 - 核心模块初始化顺序,根据ctx创建上下文
  13. MacBook安装jdk8
  14. D语言使用dub编译ms-coff文件
  15. 小程序商城如何精细化运营?
  16. WUST-CTF2020(武汉科技大学第一届WUST-CTF网络安全竞赛)WP
  17. ch341a编程和ttl刷机区别_USB转TTL(CH341A)的注意事项及说明 -
  18. MYSQL主从部署(Censo:6)
  19. android airplay音乐播放器,您需要知道的关于使用AirPlay播放音乐的一切 | MOS86
  20. 分享Silverlight/Windows8/WPF/WP7/HTML5周学习导读(6月18日-6月24日)

热门文章

  1. 基于dnn的车牌识别_自然场景中文文字识别,身份证火车票都能识别
  2. python 切片_全面解读Python高级特性切片
  3. cocos2d-x 3.0rc2中读取sqlite文件
  4. 关中断是否禁止任务调度?关中断能作为互斥吗?
  5. ios开发第一步--虚拟机安装MAC OS X
  6. ionic 中文 API CSS and javascript link
  7. sql面试语句与后台调用js提示语句
  8. Teams Meeting App的 task 弹出框
  9. keep-alive使用_如何使用Google Keep进行无忧笔记
  10. 用c语言复制字符串的元音字母,急求:编写程序,将一个字符串中的元音字母复制到另一个字符串,然后输出。...