Java编程思想——第17章 容器深入研究 读书笔记(四)
九、散列与散列码
HashMap使用equals()判断当前的键是否与表中存在的键相同。
正确的equals()方法需满足一下条件:
1)自反性。x.equals(x) 是true;
2)对称性。x.equalse(y) 返回true y.equals(x)也得是true;
3)传递性。x.equals(y) 返回true ,y.equals(z) 返回true , x.equals(z)返回true;
4)一致性。如果对象中用于等价比较的信息没有变,那么无论多少次 x.equals(y)返回值不会变
5)x.equals(null) 返回 false ;注意:(null).equals(x)报空指针。
强调:默认的Object.equals()只比较对象的地址,因此如果使用自己的类作为HashMap的Key,必须同时重载hashCode()和equals()。
hashCode()并不需要总是能够返回唯一的标识码,但是equals()方法必须严格的判断两个对象是否相等,作为键必须唯一否则系统报错。
@Override public boolean equals(Object o) { return o instanceof T && (i.equals(((T) o).i))); }
instanceof检查了此对象是否为null ,是null则返回false。
为速度而散列
以线性查询的是最慢的查询方式,存储一组元素最快的数据结构是数组,所以使用它来标识键的信息(注意,这里说的是键信息不是键本身)。
由于数组不能调整容量,所以数组不保存键本身,而是通过键对象生成一个散列码,将其作为数组的下标,这个散列码就是由Object中的、或自己的类覆盖的hashCode()生成的。
数组固定的问题解决了,但是键可以产生相同的下标,也就是说可能会有冲突。数组多大不重要,任何键总能在数组中找到它的位置。
于是,查询一个值的过程首先就是计算散列码,然后使用散列码查找数组。如果能够保证没有冲突(如果被查询的值的数量是固定的,就有可能)。
通常,冲突由外部链接处理;数组并不直接保存值,而是保存值的list。然后对list中的值使用equals()方法进行线性查询。
这部分查找会比较慢,但是如果散列函数好的话,数组每个位置就有较少的值。
因此,不是查询整个List而是快速的跳转到数组的某个位置,只对很少的元素进行比较。这就是HashMap会如此快的原因。
我们把散列表的数组称为bucket(桶),为了散布均匀且速度快,桶的容积通常使用质数或者2的整数次方,用LinkedList填充桶。
put()操作,计算key的hashCode(),找到桶中的位置,看LinkedList内容,有值用equals()与值的key相比,相等就替换,不等或者没有值就在尾部加上新值。
覆盖hashCode()
桶下标值是无法控制的,这个值依赖于具体的HashMap对象的容量,而容量的改变与容器的充满程度和负载因子有关。hashCode()生成的结果,经过畜栏里后成为桶位的下标。
Joshua Blochw指出为写出一份像样的hashCode给出了知道:
1)给 int 变量 result 赋予某个非0常量,
2)为对象内每个有意义的域f(既每个可以做equals()操作的域)计算一个int 散列码 c:
域类型: 计算:
boolean c=(f?0:1)
byte、char、short、int c=(int)f
float c=(int)(f^(f>>>32))
double long I =Double.doubleToLongBits(f); c=(int)(I^(I>>>32))
Object,其equals()调用这个域的equals() c=f.hashCode()
数组 对每个元素应用上述规则
3)合并计算得到散列码
result = 37*result+c
Java编程思想——第17章 容器深入研究 读书笔记(四)的更多相关文章
- Java编程思想——第17章 容器深入研究 读书笔记(三)
七.队列 排队,先进先出. 除并发应用外Queue只有两个实现:LinkedList,PriorityQueue.他们的差异在于排序而非性能. 一些常用方法: 继承自Collection的方法: ad ...
- Java编程思想——第17章 容器深入研究 读书笔记(二)
五.List的功能方法 排除Collection已包含的方法外还增加了 boolean addAll(int index, Collection<? extends E> c);从索引位置 ...
- Java编程思想——第17章 容器深入研究 读书笔记(一)
这一章将学习散列机制是如何工作的,以及在使用散列容器时怎么样编写hashCode()和equals()方法. 一.容器分类 先上两张图 来概况完整的容器分类 再细说都为什么会有那些特性. 二.填充容器 ...
- Java编程思想——第17章 容器深入研究(two)
六.队列 排队,先进先出.除并发应用外Queue只有两个实现:LinkedList,PriorityQueue.他们的差异在于排序而非性能. 一些常用方法: 继承自Collection的方法: add ...
- Java编程思想——第17章 容器深入研究(一)
这一章将学习散列机制是如何工作的,以及在使用散列容器时怎么样编写hashCode()和equals()方法. 一.容器分类 先上两张图 来概况完整的容器分类 再细说都为什么会有那些特性. 二.Coll ...
- Java编程思想(11~17)
[注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第十一章 持有对象 11.1 泛型和类型安全的容器>eg: List<St ...
- Java编程思想 第21章 并发
这是在2013年的笔记整理.现在重新拿出来,放在网上,重新总结下. 两种基本的线程实现方式 以及中断 package thread; /** * * @author zjf * @create_tim ...
- Java编程思想——第14章 类型信息(一)
运行时类型信息使得你可以在程序运行时发现和使用类型信息.Java是如何让我们在运行时识别对象和类的信息得呢? 主要有两种方式:1.传统RTTI,他假定我们在编译期间已经知道了所有类型:2.反射,它允许 ...
- Java编程思想(第一章 对象入门)总结
面向对象编程(oop) 1.1抽象的进步 所有编程语言的最终目的都是提供一种“抽象”方法. 难点是 在机器模型(位于“方案空间”)和实际解决问题模型(位于“问题空间”)之间,程序员必须建立起一种联 ...
随机推荐
- MySQL索引原理及SQL优化
目录 索引(Index) 索引的原理 b+树 MySQL如何使用索引 如何优化 索引虽好,不可滥用 如何验证索引使用情况? SQL优化 explain查询执行计划 id select_type tab ...
- 【深入浅出-JVM】(77):SPI
概念 Service Provider Interface 规则 在resource/META-INF/services 创建一个以接口全限定名为命名的文件,内容写上实现类的全限定名 接口实现类在cl ...
- elk安装和使用
elk安装和使用 使用的版本都是5.2.0 elasticsearch-5.2.0安装 在官网 下载 elasticsearch tar包 解压安装 tar zxf elasticsearch-5.2 ...
- VMware Workstation Fixed Unable to connect to the MKS
场景:早上开虚拟机时突然报这个错 解决办法如下: 以管理员的身份打开CMD,然后执行如下命令: net start vmx86 net start hcmon net start vmauthdser ...
- Linux 笔记 - 第六章 Linux 磁盘管理
博客地址:http://www.moonxy.com 一.前言 1.1 硬盘 硬盘一般分为 IDE 硬盘.SCSI 硬盘和 SATA 硬盘.在 Linux 中,IDE 接口的设备被称为 hd,SCSI ...
- 【PyTorch】Tricks 集锦
声明:本文大部分内容是从知乎.博客等知识分享站点摘录而来,以方便查阅学习.具体摘录地址已在文章底部引用部分给出. 1. 查看模型每层输出详情 from torchsummary import summ ...
- (七十二)c#Winform自定义控件-雷达图
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- jenkins插件之Publish Over SSH的使用
1,安装 在插件管理选项搜索Publish Over SSH,然后点击安装即可完成 2,安装完成之后,就可以在jenkins的配置系统中找到Publish Over SSH 配置完服务器之后,然后在项 ...
- 基于操作系统原理的Linux 系统的安装
一.实验目的 1.了解Linux操作系统的发行版本. 2.掌握Red Hat Linux 9.0的安装方法. (可用Red Hat Linux 5.0版本替代9.0版本) 3.了解Linux其他版本( ...
- aapt的具体使用
一.什么是aapt: aapt Android Asset Packaging Tool android的一个资源打包工具 二.配置aapt路径: aapt这个工具,在sdk的build-tools下 ...