《C#高效编程》读书笔记07-理解GetHashCode()的陷阱
GetHashCode()函数仅会在一个地方用到,即为基于散列(hash)的集合定义的散列键时,此类集合包括HashSet和Dictionary<K,V>容器等。
但object基类提供的GetHashCode()实现有很多问题。
- 对于引用类型,虽然可以正常工作,但效率很低
- 对于值类型,基类中的实现有时甚至是不正确的
如果我们定义的类型不会在容器中作为键来使用,那就没有什么问题。但如果创建的类型将被当做散列表中的键使用,那么就需要自己实现GetHashCode()。
重载GetHashCode()必须遵循以下规则:
- 如果两个对象相对(由operator==定义),那么它们必须生成相同的散列码。否则,这样的散列码将无法用来查找容器中的对象。
- 对于任何一个对象A,A.GetHashCode()必须保持不变。不管在A上调用什么方法,A.GetHashCode()都必然总是返回同一个值。这可以确保放在“桶”中的对象总是位于正确的“桶”中。
- 对于所有的输入,散列函数应该在所有整数中按照随机分布生成散列码。这样散列容器才能得到足够的效率提升。
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()的陷阱的更多相关文章
- CSAPP 并发编程读书笔记
CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
- unix环境高级编程-读书笔记与习题解答-第一篇
从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...
- MacTalk·人生元编程 - 读书笔记
简介 <MacTalk·人生元编程>是一本随笔文集,主要内容来自作者的微信公众平台"MacTalk By 池建强".本书撰写于2013年,书中时间线却不止于此.作者以一 ...
- 20150206读书笔记<深入理解计算机系统>
●第一章 C是系统级编程的首选.C++显示支持抽象,属于应用级程序设计语言. 简单例子: 一个典型系统的硬件组成: 存储器的层次结构: 注:存储器层次结构的设计思想是,该层存储器作为下一层存储器的高速 ...
随机推荐
- PopupWindow-----listview item的点击出现PopupWindow
/** * 设置listview item的点击事件 */ lv_app_manager.setOnItemClickListener(new OnItemClickListener() { @Ove ...
- [xdoj1158]阶乘求逆元(常用于求组合数)
http://acm.xidian.edu.cn/problem.php?id=1158 解题关键:此题注意将$\sum\limits_{i = 0}^x {C_x^iC_y^{i + k}}$转化为 ...
- 使用showMessageDialog显示消息框
-----------------siwuxie095 工程名:TestJOptionPane 包名:com.siwuxie095.showdialog ...
- SpringBoot05 数据操作03 -> JPA查询方法的规则定义
请参见<springboot详解>springjpa部分知识 1 按照方法命名来进行查询 待更新... package cn.xiangxu.springboot.repository; ...
- SSM框架集成Redis
SSM-Spring+SpringMVC+Mybatis框架相信大家都很熟悉了,但是有的时候需要频繁访问数据库中不变或者不经常改变的数据,就会加重数据库的负担,这时我们就会想起Redis Redis是 ...
- 2. DVWA亲测命令执行漏洞
先看low级: 提示让我们输入一个IP地址来实现ping,猜测会是在系统终端中实现的, 我们正常输入127.0.0.1: 那我们就可以利用这个使用其他CMD命令 我们输入127.0.0.1& ...
- PCC-S-02201, Encountered the symbol "DB_USER_OPER_COUNT"
今天编译PROC程序时,遇到这个错误.最后发现原因是.pc文件里声明变量块时,不识别结构体. 今天时间紧知识用第一种方法暂时解决了.晚上抽时间用第二种方法优化一下代码. 查了很多资料,发现只有这个答案 ...
- Codeforces Round#522 Div2E(思维,背包,组合数学)
#include<bits/stdc++.h>using namespace std;int a[107];int b[10007][107];int c[107][107];int ma ...
- bzoj 2827: 千山鸟飞绝
2827: 千山鸟飞绝 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 802 Solved: 228[Submit][Status][Discuss ...
- java整理(三)
1.继承性:继承已有的功能.使用extends关键字.class 子类 extends 父类{} 子类又被称为派生类,父类又被称为超类. 继承的限制: 1.java中,不允许多重继承,即一个子 ...