GetHashCode()函数仅会在一个地方用到,即为基于散列(hash)的集合定义的散列键时,此类集合包括HashSet和Dictionary<K,V>容器等。
但object基类提供的GetHashCode()实现有很多问题。

  • 对于引用类型,虽然可以正常工作,但效率很低
  • 对于值类型,基类中的实现有时甚至是不正确的

如果我们定义的类型不会在容器中作为键来使用,那就没有什么问题。但如果创建的类型将被当做散列表中的键使用,那么就需要自己实现GetHashCode()。
重载GetHashCode()必须遵循以下规则:

  1. 如果两个对象相对(由operator==定义),那么它们必须生成相同的散列码。否则,这样的散列码将无法用来查找容器中的对象。
  2. 对于任何一个对象A,A.GetHashCode()必须保持不变。不管在A上调用什么方法,A.GetHashCode()都必然总是返回同一个值。这可以确保放在“桶”中的对象总是位于正确的“桶”中。
  3. 对于所有的输入,散列函数应该在所有整数中按照随机分布生成散列码。这样散列容器才能得到足够的效率提升。

Object.GetHashCode()使用System.Object中的一个内部字段来产生序列值。系统创建的每一个对象在创建时都会被指派给一个唯一的对象键(一个整数值)。这些键从1开始,每创建一个任意类型的新对象,键值都会随之增长。对象标识字段会在System.Object构造函数中设置,并且之后不能更改。对于一个指定的对象,Object.GetHashCode()会返回该值作为散列码。

但其实Object.GetHashCode()并不满足第三条规则,一个递增序列在所有整数范围内显然不是一个随机分布。Object.GetHashCode()返回的散列码会集中在整数范围的低端。这就意味着Object.GetHashCode()的实现虽说是正确的,但效率不够好。
System.VauleType覆写GetHashCode()方法,为所有值类型提供了一个默认实现。默认的实现会返回类型中定义的第一个字段散列码。只有当值类型的第一个字段是只读的情况下,VauleType.GetHashCode()才能正常工作。只有当值类型第一个字段包含的值有着相对随机分布时,VauleType.GetHashCode()才会产生一个比较高效的散列码。

《C#高效编程》读书笔记07-理解GetHashCode()的陷阱的更多相关文章

  1. CSAPP 并发编程读书笔记

    CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...

  2. 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化

    <深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...

  3. Node.js高级编程读书笔记Outline

    Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...

  4. C++Windows核心编程读书笔记

    转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...

  5. 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...

  6. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

  7. unix环境高级编程-读书笔记与习题解答-第一篇

    从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...

  8. MacTalk·人生元编程 - 读书笔记

    简介 <MacTalk·人生元编程>是一本随笔文集,主要内容来自作者的微信公众平台"MacTalk By 池建强".本书撰写于2013年,书中时间线却不止于此.作者以一 ...

  9. 20150206读书笔记<深入理解计算机系统>

    ●第一章 C是系统级编程的首选.C++显示支持抽象,属于应用级程序设计语言. 简单例子: 一个典型系统的硬件组成: 存储器的层次结构: 注:存储器层次结构的设计思想是,该层存储器作为下一层存储器的高速 ...

随机推荐

  1. js提交数据时需判断是点击事件还是回车键

    使用回车键实质还是点击事件==回车时将焦点聚居在某个标签上. Html代码: <div id="btlogin" class="btlogin">& ...

  2. Learning Python 008 正则表达式-001

    Python 正则表达式 总结 这节课讲讲正真使用的技术 - 正真表达式. 文本爬虫 什么是正则表达式 正则表达式这个名词听起来就有一种很官方的感觉,但是它是一个很很很有用的技术.我用语言是不能形容它 ...

  3. <c和指针>学习笔记5动态内存分配和预处理器

    1 动态内存 比如声明数组得时候,我们需要提前预估数组长度,分配大了浪费,少了就更不好操作了.从而引入动态分配,需要的时候再分配. (1)malloc和free void *malloc(size_t ...

  4. jquery插件-自由拖拽

    最近工作不是很忙,学习之余想整理一些代码出来,首先想到的就是是js拖拽. 两年前去某公司面试的时候,曾经被问过这个问题,如何在页面上拖放元素,尽管现在看起来很简单,但当时的我半点思路都没有,面试想当然 ...

  5. Python开发【第五篇】:函数

    1. 函数   函数是组织好的,可重复使用的,用来实现单一,或相关功能的代码块.   函数分为 Python 程序内置函数,用户自定义的函数.将代码定义为函数,有如下好处: 代码重用(某个特定功能复用 ...

  6. Sharepoint2013商务智能学习笔记之部署AdventureWorksDW2012数据库(三)

    AdventureWorksDW2012是sql server2012的样本数据库,后面做商务智能Demo会用到,所以需要下载并安装到sql server2012上,下载地址 第一步,下载数据库 第二 ...

  7. 如何使用visual studio 2017创建C语言项目

    使用visual studio 2017创建一个C语言项目,步骤如下: (1)打开Visual Studio 2017环境后出现欢迎界面,如图1所示. 图1  Visual Studio 2017欢迎 ...

  8. vim 设置TAB宽度、显示行号、自动缩进、自动换行宽度

    一.vim  ~/.vimrc 二.添加如下几行:(括号中的不是,是我添加的) set shiftwidth=4          (表示每一级缩进的长度)set softtabstop=4     ...

  9. uva 1614奇怪的股市(归纳法证明,贪心)

    uva 1614奇怪的股市(归纳法证明,贪心) 输入一个长度为n的序列a,满足\(1\le a_i\le i\),要求确定每个数的正负号,使得所有数的总和为0.例如a={1, 2, 3, 4},则4个 ...

  10. [Xcode 实际操作]四、常用控件-(2)UIButton图片按钮的使用

    目录:[Swift]Xcode实际操作 本文将演示图片按钮的使用 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class ViewCo ...