《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 ...
随机推荐
- vue实践---vue结合 promise 封装原生ajax
有时候不想使用axios这样的外部依赖,想自己封装ajax,这里有两种方法 方法一,在单个页面内使用 封装的代码如下: beforeCreate () { this.$http = (() => ...
- 创建有提示的ui组件
using UnityEditor; using UnityEngine; using System.Collections; using Edelweiss.CloudSystem; namespa ...
- ULN2003A 使用,有坑
8脚接24V负极 9脚接24V正极 16接24V继电器,再接到24V正极 1-7无论给5V 正 或 负,10-16都不能达到24V,越靠近输入端的输出端电压越大,最大的才11V,最小的2.5V 最后发 ...
- asp.net mvc 反射应用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页
协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...
- MediaRecorder实现微信、QQ、人人、易信等语音录制功能工具:MediaUtilAPI
本文介绍使用MediaRecorder进行录制音频.录制视频学习,熟悉MediaRecorder执行流程,通过简单的Demo结合解释运行效果,最后封装MediaRecorder的API工具,实现常见比 ...
- spring属性注入方式
一.使用有参构造注入属性 配置文件 constructor-arg标签是需注入属性的名字 User类 生成了User的有参构造函数 测试类 结果 打印出了name属性的值 二.使用set方法注入属性 ...
- Spark0.9.0机器学习包MLlib-Optimization代码阅读
基于Spark的一个生态产品--MLlib,实现了经典的机器学算法,源码分8个文件夹,classification文件夹下面包含NB.LR.SVM的实现,clustering文件夹下面包 ...
- 读:Instance-aware Image and Sentence Matching with Selective Multimodal LSTM
摘要:有效图像和句子匹配取决于如何很好地度量其全局视觉 - 语义相似度.基于观察到这样的全局相似性是由图像(对象)和句子(词)的成对实例之间的多个局部相似性的复合聚集,我们提出了一个实例感知图像和句子 ...
- Java进阶学习:log4j的学习和使用
Java进阶学习——log4j的学习和使用 简介Loj4j Log4j的组成 Log4j主要由三大组组件构成: Logger: 负责生成日志,并能够对日志信息进行分类筛选,通俗的讲就是决定什么日志信息 ...