• C# 对象哈希码


    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对象应返回相同哈希码.

  • 相关阅读:
    .net Thrift 之旅 (一) Windows 安装及 HelloWorld
    软件测试中的过度设计
    血型和测试
    功能点算法及在软件测试中的应用Part2
    尘归尘 土归土
    解读SAO文化中的Share
    使用C#开发winform程序的界面框架
    怎样才能说明软件测试工作做的好?
    功能点算法及在软件测试中的应用Part1
    软件测试的核心价值是什么?
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/7827963.html
Copyright © 2020-2023  润新知