FCL的设计者认为,如果能将任何对象的任何实例放到哈希集合中,能带来很多好处。但是这里说一点,还是会存在,哈希码类似的情况,这一点大型网站架构这本书中有介绍,最好做下MD5算法.为此,System.Object提供了GetHashCode,它能获取任何对象的Int32哈希码.如果你定义的类型重写了Equals方法,还应重写GetHashCode方法。如果你的类型重写了Equals方法,但是没有重写GetHashCode方法,C#编译器会发出一条警告,提示你重写GetHashCode方法,之所以重写Equals方法的同时要求重写GetHashCode的原因是由于在System.Collection.HashTable类型、System.Collection.Generic.Dictionary类型以及其他的一些集合的实现中,要求两个对象必须有相等的哈希值才被视为相等。所以重写Equals就必须重写GetHashCode,确保相等性算法和对象哈希码算法一致.

简单分析下向集合中添加键值对的哈希过程:

1、向集合中添加键值对,第一步是获取键对象的哈希码

2、根据该哈希码(将哈希码作为标识),将键值对存储到指定的哈希桶中

再分析下根据键查找集合中的对应的值的过程:

1、获取键的哈希码

2、该哈希码标识了现在要以顺序的方式搜索哈希桶

3、根据该哈希码查找与指定键对象相等的键对象.

但是,采用这个算法来存储和查找键,一旦修改了一个键对象,键对应的哈希码并不会进行相应的更新,该哈希码对应的键值对还挂在这个hash码下,所以这就导致了集合再也找不到这个对象。所以,需要修改哈西表中的键对象时,正确的做法是移出原来的键值对,

修改键对象,将新的键值对对象添加回哈希表.

自定义GetHashcode方法或许不是一件难事,但取决于数据类型和数据分布情况,可能并不容易设计出能返回良好分布值的哈希算法。

选择算法来计算类型实例的哈希码时,请遵守一下规则:

1、这个算法要提供良好的随机分布,使哈希表获得最佳的性能

2、可在算法中调用基类的GetHashCode方法,并包含它的返回值,但一般不要调用Object或ValueType的GetHashCode方法,因为两者的实现都与高性能哈希算法不沾边.

3、算法至少使用一个实例字段

4、理想情况下,算法使用的字段应该不可变,也就是说,字段应在对象构造时初始化,在对象生存期"永不改变"

5、算法执行速度尽量快

6、包含相同值的不同对象应返回相同的哈希码。例如,包含相同文本的两个String对象应返回相同哈希码.

C# 对象哈希码的更多相关文章

  1. [CLR via C#]5.4 对象哈希码和dynamic基元类型

    原文:[CLR via C#]5.4 对象哈希码和dynamic基元类型 FCL的设计者认为,如果能将任何对象的任何实例放到一个哈希表集合中,会带来很多好处.为此,System.Object提供了虚方 ...

  2. JAVA中的各种 哈希码(HashCode) 与 equals方法在HIBERNATE的实际应用[转载]

    1.什么是哈希码(HashCode) 在Java中,哈希码代表对象的特征.例如对象 Java代码 String str1 = “aa”, str1.hashCode= 3104 String str2 ...

  3. 什么是哈希码(HashCode)

    什么是哈希码(HashCode) 在Java中,哈希码代表对象的特征. 例如对象 String str1 = “aa”, str1.hashCode= 3104 String str2 = “bb”, ...

  4. 如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗?

    如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗? ----答案是 可以 原因: 在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了h ...

  5. Java基础知识强化48:Java中哈希码

    1.概念:      哈希其实只是一个概念,没有什么真实的指向.它的目的是保证数据均匀的分布到一定的范围内.所以不同数据产生相同的哈希码是完全可以的.      现在是站在JAVA虚拟机的角度来看内存 ...

  6. 《Beginning Java 7》 - 5 - Hash Codes 哈希码

    哈希码和 equals() 都是用来比较的. 1. 哈希码的作用是用来提高比较的效率.因为当比较的对象比较复杂时,equals() 可能很耗时,但哈希码只需要比较一个 int .哈希码常用于集 (se ...

  7. Map容器——HashMap及常用API,及put,get方法解析,哈希码的产生和使用

    Map接口 ①   映射(map)是一个存储键/值对的对象.给定一个键,可以查询到它的值,键和值都是对象; ②   键必须是唯一的,值可以重复; ③   有些映射可以接收null键和null值,而有的 ...

  8. C# 通过比对哈希码判断两个文件内容是否相同

    1.使用System.security.Cryptography.HashAlgorithm类为每个文件生成一个哈希码,然后比较两个哈希码是否一致. 2. 在比较文件内容的时候可以采用好几种方法.例如 ...

  9. Java,哈希码以及equals和==的区别

    从开始学习Java,哈希码以及equals和==的区别就一直困扰着我. 要想明白equals和==的区别首先应该了解什么是哈希码,因为在jdk的类库中不管是object实现的equals()方法还是S ...

随机推荐

  1. 可视化 linux 无法启动eclipse 报错No java virtual machine

    点击eclipse的时候会产生这个 解决方案: (1)找到eclipse的安装目录(我这个是远程连接) 注意: 点击这里可以进入命令行编辑模式 点开后 (2)给文件授权(默认是只读的) (3)对文件进 ...

  2. POJ 3621 Sightseeing Cows (bellman-Ford + 01分数规划)

    题意:给出 n 个点 m 条有向边,要求选出一个环,使得这上面 点权和/边权和 最大. 析:同样转成是01分数规划的形式,F / L 要这个值最大,也就是 G(r) = F - L * r 这个值为0 ...

  3. 20155305乔磊2016-2017-2《Java程序设计》第七周学习总结

    教材学习内容总结 第十二章 Lambda 12.1 认识Lambda语法 - Lambda 教材的引入循序渐近.深入浅出 如果使用JDK8的话,可以使用Lambda特性去除重复的信息,例: Compa ...

  4. SceneControl+AE+鼠标滚轮缩放

    要为SceneControl设置鼠标滚轮缩放必须定义委托,因为SceneControl没有Wheel事件,所以委托From的Wheel事件 public Form1() { InitializeCom ...

  5. log4j日志文件路径设置

    假设有如下标准化的目录结构: $HOME |-- log |-- conf |-- bin |-- lib |-- data jar包放在lib目录,启动脚本放在bin目录,日志文件放在log目录,配 ...

  6. PrefixHeader.pch 在工程中的使用

    1)  新建一个pch文件 2) 在 工程 Build Settings 中搜索 header  将Precompile Prefix Header 置为YES 2) 选中pch文件, 将右侧相对路径 ...

  7. (KMP 求循环节)The Minimum Length

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#problem/F The Minimum Length Time Limit: ...

  8. Python学习-28.Python中的列表切片

    在实际的业务过程中,经常有这么一个操作:取一个列表的一部分进行操作,而不影响原来的列表.也就是将原来的列表复制一个部分副本并对其进行操作. 举个完整例子: list = ['a','b','c','d ...

  9. C#默认以管理员身份运行程序实现代码

    using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; names ...

  10. 第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()

    最常用的方式: int a = 12; //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁 final Reentrant ...