以实现一个简单的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编程思想》:散列的原理的更多相关文章

  1. 《Java编程思想第四版》附录 B 对比 C++和 Java

    <Java编程思想第四版完整中文高清版.pdf>-笔记 附录 B 对比 C++和 Java “作为一名 C++程序员,我们早已掌握了面向对象程序设计的基本概念,而且 Java 的语法无疑是 ...

  2. JAVA编程思想——分析阅读

    需要源码.JDK1.6 .编码风格参考阿里java规约 7/12开始 有点意识到自己喜欢理论大而泛的模糊知识的学习,而不喜欢实践和细节的打磨,是因为粗心浮躁导致的么? cron表达式使用 设计能力.领 ...

  3. 《Java编程思想》读书笔记(二)

    三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...

  4. Java编程思想(11~17)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第十一章 持有对象 11.1 泛型和类型安全的容器>eg: List<St ...

  5. Java编程思想(后)

    Java编程思想(后) 持有对象 如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这是一个非常简单的程序. Java中的库基本类型: List, Set, Queue和Map --- 称为集 ...

  6. 《Java编程思想》阅读笔记二

    Java编程思想 这是一个通过对<Java编程思想>(Think in java)进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会忽略或 ...

  7. Java编程思想——第17章 容器深入研究 读书笔记(三)

    七.队列 排队,先进先出. 除并发应用外Queue只有两个实现:LinkedList,PriorityQueue.他们的差异在于排序而非性能. 一些常用方法: 继承自Collection的方法: ad ...

  8. Java编程思想——第17章 容器深入研究(two)

    六.队列 排队,先进先出.除并发应用外Queue只有两个实现:LinkedList,PriorityQueue.他们的差异在于排序而非性能. 一些常用方法: 继承自Collection的方法: add ...

  9. Java编程思想—八皇后问题(数组法、堆栈法)

    Java编程思想-八皇后问题(数组法.堆栈法) 实验题目:回溯法实验(八皇后问题) 实验目的: 实验要求: 实验内容: (1)问题描述 (2)实验步骤: 数组法: 堆栈法: 算法伪代码: 实验结果: ...

  10. Java编程思想 笔记

    date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...

随机推荐

  1. Java Enum 比较用 == 还是 eques

    我是把枚举当作常量来使用的,枚举中还有两个自己的属性,关注到这个地方的朋友对枚举已经有了认识,这里就不再编写枚举的demo了,这里我直接说结果吧,在枚举中使用==和equals比较效果是一样的,查看源 ...

  2. 【BZOJ2407/4398】探险/福慧双修 最短路建模

    [BZOJ2407]探险 Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作 ...

  3. Asp.Net MVC3中如何进行单元测试?

    下面我们就以一个示例演示一下如何进行单元测试? public Model.UserInfo UpdateEntity(Model.UserInfo entity) { db.UserInfo.Atta ...

  4. 梯度下降算法(gradient descent)

    简述 梯度下降法又被称为最速下降法(Steepest descend method),其理论基础是梯度的概念.梯度与方向导数的关系为:梯度的方向与取得最大方向导数值的方向一致,而梯度的模就是函数在该点 ...

  5. Android Screen Orientation

    Ref:Android横竖屏切换小结 Ref:Android游戏开发之横竖屏的切换(二十七)

  6. python基础22------python基础之基于tcp和udp的套接字

    一.TCP套接字 1.low版tcp套接字 服务器端 客户端 2.改进版tcp套接字 服务端 客户端 二.UDP的套接字 服务器 客户端 注:udp的套接字可以支持多个客户端同时访问,但tcp套接字就 ...

  7. 4django模板

    在前面的几节中我们都是用简单的django.http.HttpResponse来把内容显示到网页上,本节将讲解如何使用渲染模板的方法来显示内容 1.创建一个 zqxt_tmpl 项目,和一个 名称为 ...

  8. [原创]java WEB学习笔记01:javaWeb之tomcat的安装和配置

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  9. [原创]java WEB学习笔记15:域对象的属性操作(pageContext,request,session,application) 及 请求的重定向和转发

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  10. Python 3 并发编程多进程之队列(推荐使用)

    Python 3 并发编程多进程之队列(推荐使用) 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 可以往 ...