《java编程思想》:散列的原理
以实现一个简单的HashMap为例,详细讲解在code之中。
简单解释散列原理:
1.map中内建固定大小数组,但是数组并不保存key值本身,而是保存标识key的信息
2.通过key生成数组角标,对应位置存放LinkedList,list中存放的是键值对
3.如此,无论放入多少个键值对,数组大小都不必改变,当key值生成的角标值重复时,获取对应位置的list,向list中添加键值对即可
4.当调用get()方法时,只需遍历对应角标位置的list,而不用遍历所有的键值对信息,所以加快了查询速度。
5.注意,get()和put()中使用的计算散列值,也就是数组角标的公式一定要一致,保证计算所得的角标一致
/**
* Created by Don9 on 2017/
*/
public class MyHashMap<K,V> extends AbstractMap<K,V>{
/* 1.自定义数组大小 */
static final int SIZE = 999;
/* 2.创建内部数组,数组存放的是LinkedList,而list中存放的是想要存放的键值对 */
LinkedList<MyEntry<K,V>>[] buckets = new LinkedList[999];
/* 3.put方法,此方法返回key对应的曾经的oldValue */
public V put(K key,V value){
/* 4.先定义一个返回值 */
V oldValue = null;
/* 5.根据key计算出一个散列值,用于当作内置数组的下角标(
此公式不固定,是自定义的,但是要保证结果稳定不变,同时不能大于数组size) */
int index = Math.abs(key.hashCode()) % SIZE;
/* 6.当index位置为空时,填充新的list */
if(buckets[index]==null){
buckets[index] = new LinkedList<MyEntry<K,V>>();
}
/* 7.获取index位置的list */
LinkedList<MyEntry<K, V>> bucket = buckets[index];
/* 8.MyEntry是自定义的Entry实现类,用于保存键值对,这个类也可以自定义,只要实现接口Entry即可,
新建entry保存传入的键值对 */
MyEntry<K, V> newMe = new MyEntry<K, V>(key,value);
/* 9.定义一个found标记,用于记录是否替换完毕 */
boolean found = false;
ListIterator<MyEntry<K, V>> it = bucket.listIterator();
/* 10.遍历当前位置的list */
while(it.hasNext()){
MyEntry<K, V> oldMe = it.next();
/* 11.list中已经存在了当前key */
if(oldMe.getKey().equals(key)){
/* 12.获得oldValue值,用于返回 */
oldValue = oldMe.getValue();
/* 13.用新的entry替换老的 */
it.set(newMe);
/* 14.标记改为true,说明替换完毕 */
found = true;
/* 15.跳出 */
break;
}
}
/* 16.如果未替换完毕,也就是说key值在之前的list中不存在 */
if(!found){
/* 17.添加新的entry到list中 */
bucket.add(newMe);
}
/* 18.返回oldValue */
return oldValue;
} /* 19.定义get查找方法 */
public V get(Object key){
/* 20.生成散列值,也就是数组角标,此处一定要和put方法中生成方式一致,保证相同的key生成相同的位置 */
int index = Math.abs(key.hashCode()) % SIZE;
/* 21.index位置为null,不存在key,返回null */
if(buckets[index]==null){
return null;
}
/* 22.index位置不为null,遍历查询,返回value */
for(MyEntry<K,V> me:buckets[index]){
if(me.getKey().equals(key)){
return me.getValue();
}
}
return null;
} @Override
public Set<Entry<K, V>> entrySet() {
return null;
}
}
《java编程思想》:散列的原理的更多相关文章
- 《Java编程思想第四版》附录 B 对比 C++和 Java
<Java编程思想第四版完整中文高清版.pdf>-笔记 附录 B 对比 C++和 Java “作为一名 C++程序员,我们早已掌握了面向对象程序设计的基本概念,而且 Java 的语法无疑是 ...
- JAVA编程思想——分析阅读
需要源码.JDK1.6 .编码风格参考阿里java规约 7/12开始 有点意识到自己喜欢理论大而泛的模糊知识的学习,而不喜欢实践和细节的打磨,是因为粗心浮躁导致的么? cron表达式使用 设计能力.领 ...
- 《Java编程思想》读书笔记(二)
三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...
- Java编程思想(11~17)
[注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第十一章 持有对象 11.1 泛型和类型安全的容器>eg: List<St ...
- Java编程思想(后)
Java编程思想(后) 持有对象 如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这是一个非常简单的程序. Java中的库基本类型: List, Set, Queue和Map --- 称为集 ...
- 《Java编程思想》阅读笔记二
Java编程思想 这是一个通过对<Java编程思想>(Think in java)进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会忽略或 ...
- Java编程思想——第17章 容器深入研究 读书笔记(三)
七.队列 排队,先进先出. 除并发应用外Queue只有两个实现:LinkedList,PriorityQueue.他们的差异在于排序而非性能. 一些常用方法: 继承自Collection的方法: ad ...
- Java编程思想——第17章 容器深入研究(two)
六.队列 排队,先进先出.除并发应用外Queue只有两个实现:LinkedList,PriorityQueue.他们的差异在于排序而非性能. 一些常用方法: 继承自Collection的方法: add ...
- Java编程思想—八皇后问题(数组法、堆栈法)
Java编程思想-八皇后问题(数组法.堆栈法) 实验题目:回溯法实验(八皇后问题) 实验目的: 实验要求: 实验内容: (1)问题描述 (2)实验步骤: 数组法: 堆栈法: 算法伪代码: 实验结果: ...
- Java编程思想 笔记
date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...
随机推荐
- Linux守护进程简单介绍和实例具体解释
Linux守护进程简单介绍和实例具体解释 简单介绍 守护进程(Daemon)是执行在后台的一种特殊进程.它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种非常实用的进程. ...
- 基于react-native android的新闻app的开发
使用平台:android 代码获取地址:https://github.com/wuwanyu/ReactNative-Android-MovieDemo 项目展示: 结构图: SpalashScree ...
- Javascript获取各种浏览器可见窗口大小
function getInfo() { var s = ""; s += " 网页可见区域宽:"+ document.body.clientWidth; s ...
- Unity批量生成Prefab
在项目中有时会遇到批量生成Prefab的需求.于是写了一个编辑器,用来实现此功能. 在Hierarchy面板中选中多个GameObject,点击生成Prefab即可. 如果所选物体中包含自定义Mesh ...
- 解决ubuntu中文乱码问题
方法一: Ubuntu默认的中文字符编码为zh_CN.UTF-8,这个可以在 /etc/environment中看到:sudo gedit /etc/environment可以看到如下内容:PATH= ...
- Linux 技巧:让进程在后台运行的可靠方法
原文链接:http://www.ibm.com/developerworks/cn/linux/l-cn-nohup/ 想让进程在断开连接后依然保持运行?如果该进程已经开始运行了该如何补救? 如果有大 ...
- 【BZOJ3105】[cqoi2013]新Nim游戏 贪心+线性基
[BZOJ3105][cqoi2013]新Nim游戏 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个 ...
- vue路由vue-route
首先先引入插件 <script src="Vue.js"></script> //vue.js在前面 <script src="vue-ro ...
- l如何把SQLServer表数据导出CSV文件,并带列名
http://jingyan.baidu.com/article/4b07be3c466b5d48b280f37f.html 微信公众号:
- RLearning第2弹:创建数据集
任何一门语言,数据类型和数据结构是最基础,也是最重要的,必须要学好!1.产生向量 a<-c(1,2,5,3,6,-2,4) b<-c("one","two&q ...