扰动函数和拉链法模拟HashMap的存储结构
HashMap是Map接口下面的子孙,它对外是K,V结构存储的,而内部也着自己的存储结构,它的get操作是O(1)的时间复杂度,可以说是非常快的找到目录,而添加时,也是O(1),所以在键值存储里,它成为了我们的首选,在多线程情况下,要注意,它不是线程安全的。如果是多线程情况下,请使用ConcurrentHashMap
.
就是JDK1.8之前
JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列。HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过(n - 1) & hash
判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法
解决冲突。
我们简单起见,我们使用Map来模块Map的查找方式,真正的Map是使用数组+链表实现的。
使用数组+链表模拟Map
/**
* 原版-扰动法+拉链法
*
* @param list
* @param val
*/
void moniLinkList(LinkedList[] list, String val) {
int length = list.length;
int index = (length - 1) & val.hashCode();
LinkedList linkedList = list[index];
if (linkedList != null) {
linkedList.add(val);
} else {
linkedList = new LinkedList();
linkedList.add(val);
}
list[index] = linkedList;
}
测试一下
@Test
public void moniLinkListTest() {
LinkedList[] list = new LinkedList[8];
moniLinkList(list, "a");
moniLinkList(list, "b");
moniLinkList(list, "c");
moniLinkList(list, "d");
moniLinkList(list, "e");
moniLinkList(list, "f");
moniLinkList(list, "zzl");
for (int i = 0; i < list.length; i++) {
System.out.print(list[i] + " ");
}
}
结到我们希望的结果
null [a] [b] [c] [d, zzl] [e] [f] null
模拟你的Map的查找过程
/**
* 扰动法+拉链法.
*/
void moniMap(Map<Integer, Map<String, String>> moni, String val, int length) {
int index = (length - 1) & val.hashCode();
if (moni.containsKey(index)) {
Map<String, String> map = moni.get(index);
map.put(val, val);
} else {
moni.put(index, new HashMap<String, String>() {{
put(val, val);
}});
}
}
添加一个测试代码
@Test
public void moniTest() {
int len = 4;
Map<Integer, Map<String, String>> moni = new HashMap<>();
moniMap(moni, "a", len);
moniMap(moni, "b", len);
moniMap(moni, "c", len);
moniMap(moni, "b", len);
moniMap(moni, "e", len);
moniMap(moni, "zzl", len);
moniMap(moni, "zhl", len);
moniMap(moni, "zhz", len);
System.out.println(moni);
}
结果
{
0={zzl=zzl, zhz=zhz},
1={a=a, e=e},
2={b=b, zhl=zhl},
3={c=c}
}
从结果中我们可以看到,首先根据扰动法找到一个索引号,然后当不同hash在计算后生成了相同的索引号,这时需要走拉链法,将他们分组到一个链表里,就这样,我们看到
了一个被分组之后的数据。
扰动函数和拉链法模拟HashMap的存储结构的更多相关文章
- 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响
不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 ...
- HashMap的存储结构及原理
1.HashMap的数据结构(HashMap通过hashcode对其内容进行高速查找,是无序的) 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 :数组的存储区是连续的,占 ...
- 拉链法解决Hash节点冲突问题
<?php /* * hash::拉链法解决hash节点存储冲突问题 * ::2014-07-02 * ::Small_Kind */ class small_hash { private $s ...
- 【Java集合学习】HashMap源码之“拉链法”散列冲突的解决
1.HashMap的概念 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io ...
- 链地址法实现HashMap
前注:本文介绍的HashMap并非Java类库的实现.而是根据哈希表知识的一个实现. 上文介绍了开放地址法实现HashTable,它的缺点是对hashCode映射为地址后如果出现重复地址,则会占用其他 ...
- HashMap的存储原理
HashMap是java中相当重要的数据结构,使用HashMap的场景非常之多,因此,了解HashMap实现的过程和原理,是非常有必要的,在一些面试中也会经常被问到.好了,我们赶紧来研究java内部是 ...
- 散列表(拉链法与线性探测法)Java实现
package practice; import java.security.Principal; import java.util.Scanner; import edu.princeton.cs. ...
- HASH表的实现(拉链法)
本文的一些基本概念参考了一部分百度百科,当然只保留了最有价值的部分,代码部分完全是自己实现! 简介 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据 ...
- 拉链法解决hashtable冲突问题
拉链法解决冲突.拉链法解决冲突的做法是将所有的相同Hash值的key放在一个链表中,比如key3和key14在hash之后都是0,那么在数组的键为0的地方存储这两个值,形式是链表.如果不能理解我的文字 ...
随机推荐
- MVC使用方法
1.mvc打开html代码 后台处理: ///<summary> ///恢复html中的特殊字符 ///</summary> ...
- html中footer如何一直保持在页底
最近在开发博客过程中,遇到有些body的height是比window的height要低的,然后就出现了footer在页面中间的尴尬样子.那么这种情况怎么解决呢: 首先,写一个footer标签: < ...
- MySQL 查询优化之 Index Merge
MySQL 查询优化之 Index Merge Index Merge Intersection 访问算法 Index Merge Union 访问算法 Index Merge Sort-Union ...
- (61)zabbix网络发现规则配置实战/详解
开始配置.首先,我们需要定义发现规则,用于扫描.步骤如下 第一步 Configuration >>Discovery>>Create rule,编辑网络发现规则 如上配置,za ...
- json数据格式 与 for in
格式一: var json1={ name:'json', age:'23' }; json1.name='金毛'; 格式二: (比较安全) 属性名字里有空格或者有连字符‘-’或者有保留字例如‘fo ...
- verilog disable 用法 (易错!)
disable语句可以退出任何循环,能够终止任何begin..end块的执行,用于仿真验证中. 例如 begin:one ;i<;i=i+) begin:two ) disable one; / ...
- Elasticsearchs的安装/laravel-scout和laravel-scout-elastic的安装
安装: https://github.com/medcl/elasticsearch-rtf 先下载包 下载解压后 cd elasticsearch-rtf-master ll bin/elastic ...
- 【git】自动换行转换autocrlf
#####windows git config --global core.autocrlf true #####linux git config --global core.autocrlf inp ...
- Dajngo admin
Dajngo admin admin app Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.p ...
- win10系统中virtualbox无法安装64位系统
win10系统中virtualbox无法安装64位系统 先总结下如果想在虚拟机中安装64位的Linux系统,最好能满足这几个条件: 64位CPU 64位操作系统 64位的虚拟机软件 开启BIOS虚拟化 ...