以实现一个简单的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. angular选择器功能

    1.$event对象    $event对象其实就是潜在的jQuery事件对象,通过$event.currentTarget获取当前元素,通过$event.target获取当前元素的子元素. 例如: ...

  2. C语言基础知识【数据类型】

    C 数据类型1.在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统.变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式.2.C 中的类型可分为以下几种:序号    类 ...

  3. Linux下文件的基本操作

    文件的基本操作 新建和删除文件夹 命令#mkdir /file 在当前目录创建file文件夹 命令#rmdir /file 删除当前目录下file文件夹 复制和移动文件 命令#cp text/file ...

  4. winphone 中的指针和手势事件

    注意  有关这些主题的最新概述,请参阅指针事件和手势事件主题. 小心  W3C 指针事件规范自从在 Internet Explorer 10 中实施以来,已经经历了多次修订.此外,截止到 Intern ...

  5. 新升级!EasyNVR3.0功能概述--直播与录像

    背景介绍: 对于摄像机直播已经是我们司空见惯的需求,但是,许多用户在现有的直播的基础上更有录像的需求,并且有关于录像的删除定时等录像计划的需求,更有客户不仅需要这些功能,还需要将这些功能集成到自身的业 ...

  6. elasticsearch从入门到出门-06-剖析Elasticsearch的基础分布式架构

    这个图来自中华石杉:

  7. ibatis实现Iterate的使用 (转)

    <iterate         property="" /*可选,              从传入的参数集合中使用属性名去获取值,              这个必须是一 ...

  8. 从硬盘设计思想到RAID改良之道

    监控硬盘的前生今世关于桌面硬盘.企业级近线硬盘(NL-SAS/SATA)和监控硬盘的差别,我们在前文中已经讲得很详细,这里再换一个角度来看看. "监控硬盘是希捷和西数为视频监控定制的,典型的 ...

  9. SQL优化小结

    一 背景      客户数据库经常出现死锁.超时.查询慢等问题,数据库mssql,数据量主要表大概上千W. 二 收集信息      首先是要找出IO大.查询慢.使用频率高的脚本.直接用Profiler ...

  10. php自定义的格式化时间示例代码

    时间刚好是5分钟前,则对应的时间戳就会被格式化为5分钟前,自定义的格式化时间方法如下,感兴趣的朋友可以参考下 如:时间刚好是5分钟前,则对应的时间戳就会被格式化为5分钟前,不多说了,直接贴上代码: 复 ...