hash算法 (hashmap 实现原理)
Hash ,一般翻译做“ 散列” ,也有直接音译为“ 哈希” 的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不 同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
HASH 主要用于信息安全领域中加密算法,它把一些不同长度的信息转化成杂乱的128 位的编码, 这些编码值叫做HASH 值. 也可以说,hash 就是找到一种数据内容和数据存放地址之间的映射关系
例如字符串 hello 的哈希算法
char* value = "hello"; int key = (((((((27* (int)'h'+27)* (int)'e') + 27) * (int)'l') + 27) * (int)'l' +27) * 27 ) + (int)'o' ;。
数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易 的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法—— 拉链法,我们可以理解为“ 链表 的数组” ,如图:
HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。这可能让我们很不解,一个线性的数组怎么实现按键值对来存取数据呢?这里HashMap有做一些处理。
1.首先HashMap里面实现一个静态内部类Entry 其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基 础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。
2.既然是线性数组,为什么能随机存取?这里HashMap用了一个小算法,大致是这样实现:
- 存储时:
- int hash = key.hashCode();--> 这个hashCode方法这里不详述,只要理解每个key的hash是一个固定的int值
- int index = hash % Entry[].length;
- Entry[index] = value;
- 取值时:
- int hash = key.hashCode();
- int index = hash % Entry[].length;
- return Entry[index]
到这里我们轻松的理解了HashMap通过键值对实现存取的基本原理
3.疑问:如果两个key通过hash % Entry[].length得到的index相同,会不会有覆盖的危险?
这里HashMap里面用到链式数据结构的一个概念.上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方, 第一个键值对A进来,通过计算其key的hash得到的index=0,记做:Entry[0] = A.一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,index也等于0,那么C.next = B,Entry[0] = C;这样我们发现index=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起。所以疑问不用担心。
到这里为止,HashMap的大致实现,我们应该已经清楚了。
当然HashMap里面也包含一些优化方面的实现,这里也啰嗦一下。
比如:Entry[]的长度一定后,随着map里面数据的越来越长,这样同一个index的链就会很长,会不会影响性能?
HashMap里面设置一个因素(也称为因子),随着map的size越来越大,Entry[]会以一定的规则加长长度。
解决hash冲突的办法
1)开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列)
2)再哈希法
3)链地址法
4)建立一 公共溢出区
java 中hashmap的解决办法就是采用的链地址法
hash算法 (hashmap 实现原理)的更多相关文章
- Hash算法初见
hash算法 (hashmap 实现原理) Hash ,一般翻译做“ 散列” ,也有直接音译为“ 哈希” 的,就是把任意长度的输入(又叫做预映射, pre-image ),通过散列算法,变换成固定 ...
- HashMap实现原理(转)
来自:http://www.cnblogs.com/xwdreamer/archive/2012/05/14/2499339.html 0.参考文献: hash算法 (hashmap 实现原理) Ja ...
- 一致性Hash算法原理,java实现,及用途
学习记录: 一致性Hash算法原理及java实现:https://blog.csdn.net/suifeng629/article/details/81567777 一致性Hash算法介绍,原理,及使 ...
- HashMap实现原理及源码分析(jdk1.8)
HashMap底层由数组+链表+红黑树组成,可接受null值,非线程安全 1.基本属性 transient Node<K,V>[] table; //hashmap数组 static fi ...
- Hash算法及java HashMap底层实现原理理解(含jdk 1.7以及jdk 1.8)
现在很多公司面试都喜欢问java的HashMap原理,特在此整理相关原理及实现,主要还是因为很多开发集合框架都不甚理解,更不要说各种其他数据结构了,所以造成面子造飞机,进去拧螺丝. 1.哈希表结构的优 ...
- hash算法原理及应用漫谈【加图版】
原文:https://blog.csdn.net/Tencent_TEG/article/details/103021226 提到hash,相信大多数同学都不会陌生,之前很火现在也依旧很火的技术区块链 ...
- 【Java深入研究】11、深入研究hashmap中的hash算法
一.简介 大家都知道,HashMap中定位到桶的位置 是根据Key的hash值与数组的长度取模来计算的. JDK8中的hash 算法: static final int hash(Object key ...
- JDK1.8中HashMap的hash算法和寻址算法
JDK 1.8 中 HashMap 的 hash 算法和寻址算法 HashMap 源码 hash() 方法 static final int hash(Object key) { int h; ret ...
- 分布式缓存技术memcached学习(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到“分布式一致性hash算法”这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前,我们先来了解一下这几 ...
随机推荐
- AntData.ORM框架 之 读写分离
环境准备 准备2台机器配置好Master Slaver模式 我是用vmware 2台虚拟机配置的.有需要请联系. Master:192.168.11.130 Slaver:192.168.11.133 ...
- css弹性盒子新旧兼容
前言:本篇随笔是对弹性盒子有了解的人来写的这篇文章,具体属性产生的效果这里不做说明,基础的东西去查文档.这里只是总结. 时至今日,css3的flex弹性盒子在移动端基本上都是支持的,但不排除有些些低版 ...
- tr 命令详解
tr 作用:标准输入中通过替换或删除操作进行字符转换 语法:tr -c -d -s ["string1_to_translate_from"] ["string2_to ...
- Git详解之三:Git分支
Git 分支 几乎每一种版本控制系统都以某种形式支持分支.使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作.在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的 ...
- 深入浅出Android之学习笔记
1.查看启动log [2011-01-11 14:44:21 - BMI] Android Launch! [2011-01-11 14:44:21 - BMI] adb is running nor ...
- JSON 序列化和解析
概述 JSON 即 (Javascript Object Notation,Javascript 对象表示法),是在Javascript中写结构化数据的方式.而JSON本身只是一种数据格式. 通常开发 ...
- MicroPython-TPYBoard固件编译教程
本文主要介绍一下,在Linux环境下编译micropython固件的方法和流程. 首先,我们先来看一下MicroPython的源码结构. github地址:https://github.com/mic ...
- tab页切换
做了一个tab页切换.点击不同tab,显示对应的内容信息 如图 =================HTML===================== <!doctype html public ...
- 见招拆招-PostgreSQL中文全文索引效率优化
* { color: #3e3e3e } body { font-family: "Helvetica Neue", Helvetica, "Hiragino Sans ...
- express学习之session
最新版本的express没有包含session依赖项,需要我们自己配置并安装. 安装方法:npm install express-session 使用:var session = require('e ...