NET问答: 重写了 Equals,还有必要重写 GetHashCode 吗?
咨询区
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 要作为 Dictionary
和 HashSet
中的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 程序的惯用习惯,推荐再重写一下 ==
和 !=
操作符。
点评区
这个问题其实非常经典, Equals
和 GetHashCode
到底是什么关系呢?
我个人认为:在复杂类型的比较中, 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 吗?相关推荐
- float foo=42e1为什么错_为什么重写了equals()也要重写hashCode()
小Hub领读: 虽然是很基础的一篇文章,但是对于equals.hashcode两个方法,相信很多人都与其中的规则不熟悉,来跟着小Hub花个8分钟回顾一下! 作者:不学无数的程序员 https://my ...
- 为什么重写equals时必须重写hashCode方法?
2019独角兽企业重金招聘Python工程师标准>>> 首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashco ...
- Java的重写equals但不重写hashCode方法的影响
首先,说下equals和hashCode的关系.JDK API中关于Object类的equals和hashCode方法中说过,总结起来就是两句话:equals相等的两个对象的hashCode也一定相等 ...
- 为什么重写equals方法必须重写hashcode方法
想要知道这个问题,首先需要知道hashcode它的作用: HashCode的作用: 首先来看HashCode的作用,当把对象加入HashSet中时,HashSet会先计算对象的hashcode值来判断 ...
- java 为什么重写equals一定要重写hashcode?
前言 最近复习,又看到了这个问题,在此记录和整理,通过例子来说明这种情况的原因,使大家可以清晰明白这个问题. 初步探索 首先我们要了解equals方法是什么,hashcode方法是什么. equals ...
- 为什么重写equals一定要重写hashCode方法?
大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 下面我们看下Objec ...
- 重写equals就必须重写hashCode的原理分析
因为最近在整理Java集合的源码, 所以今天再来谈谈这个古老的话题,因为后面讲HashMap会用到这个知识点, 所以重新梳理下. 如果不被重写(原生Object)的hashCode和equals是什么 ...
- Java实现二树杈_HashSet的hashCode方法和equals方法的重写,TreeSet中compareTo方法的重写,Comparator在treeSet中的应用。...
HashSet的hashCode方法和equals方法的重写,TreeSet中compareTo方法的重写,Comparator在treeSet中的应用. HashSet: 首先,hashset底层是 ...
- java equals重写原则_java中为何重写equals时必须重写hashCode方法详解
前言 大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 在上一篇博文Ja ...
- java重写面试题_Java面试题:重写了equals方法,为什么还要重写hashCode方法?
核心问题:重写了equals方法,为什么还要重写hashCode方法? 这不仅仅是一道面试题,而且是关系到我们的代码是否健壮和正确的问题.在前面两篇文章涉及到了equals方法的底层讲解:<说说 ...
最新文章
- 一起学spring--依赖注入---简单粗暴的例子展示
- #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined解释
- 1100 Mars Numbers (20 分)【难度: 一般 / 知识点: 模拟】
- 【Linux】一步一步学Linux——whereis命令(15)
- 微信开放平台全网发布时,检测失败 —— C#
- 台阶问题练习题 (简单的dp)
- SpringMVC 文件上传
- vba 判断是否为数字
- T05 FX 试打报告
- OpenStack Trove2
- 搭建高可用 RocketMQ 集群
- Nginx源码分析 - 核心模块初始化顺序,根据ctx创建上下文
- MacBook安装jdk8
- D语言使用dub编译ms-coff文件
- 小程序商城如何精细化运营?
- WUST-CTF2020(武汉科技大学第一届WUST-CTF网络安全竞赛)WP
- ch341a编程和ttl刷机区别_USB转TTL(CH341A)的注意事项及说明 -
- MYSQL主从部署(Censo:6)
- android airplay音乐播放器,您需要知道的关于使用AirPlay播放音乐的一切 | MOS86
- 分享Silverlight/Windows8/WPF/WP7/HTML5周学习导读(6月18日-6月24日)
热门文章
- 基于dnn的车牌识别_自然场景中文文字识别,身份证火车票都能识别
- python 切片_全面解读Python高级特性切片
- cocos2d-x 3.0rc2中读取sqlite文件
- 关中断是否禁止任务调度?关中断能作为互斥吗?
- ios开发第一步--虚拟机安装MAC OS X
- ionic 中文 API CSS and javascript link
- sql面试语句与后台调用js提示语句
- Teams Meeting App的 task 弹出框
- keep-alive使用_如何使用Google Keep进行无忧笔记
- 用c语言复制字符串的元音字母,急求:编写程序,将一个字符串中的元音字母复制到另一个字符串,然后输出。...