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的存储结构的更多相关文章

  1. 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响

    不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑          ...

  2. HashMap的存储结构及原理

    1.HashMap的数据结构(HashMap通过hashcode对其内容进行高速查找,是无序的) 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 :数组的存储区是连续的,占 ...

  3. 拉链法解决Hash节点冲突问题

    <?php /* * hash::拉链法解决hash节点存储冲突问题 * ::2014-07-02 * ::Small_Kind */ class small_hash { private $s ...

  4. 【Java集合学习】HashMap源码之“拉链法”散列冲突的解决

    1.HashMap的概念 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io ...

  5. 链地址法实现HashMap

    前注:本文介绍的HashMap并非Java类库的实现.而是根据哈希表知识的一个实现. 上文介绍了开放地址法实现HashTable,它的缺点是对hashCode映射为地址后如果出现重复地址,则会占用其他 ...

  6. HashMap的存储原理

    HashMap是java中相当重要的数据结构,使用HashMap的场景非常之多,因此,了解HashMap实现的过程和原理,是非常有必要的,在一些面试中也会经常被问到.好了,我们赶紧来研究java内部是 ...

  7. 散列表(拉链法与线性探测法)Java实现

    package practice; import java.security.Principal; import java.util.Scanner; import edu.princeton.cs. ...

  8. HASH表的实现(拉链法)

    本文的一些基本概念参考了一部分百度百科,当然只保留了最有价值的部分,代码部分完全是自己实现! 简介 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据 ...

  9. 拉链法解决hashtable冲突问题

    拉链法解决冲突.拉链法解决冲突的做法是将所有的相同Hash值的key放在一个链表中,比如key3和key14在hash之后都是0,那么在数组的键为0的地方存储这两个值,形式是链表.如果不能理解我的文字 ...

随机推荐

  1. java HttpServletRequest 重复流读取

    在用reset接口的时候,常常会使用request.getInputStream()方法,但是流只能读取一次,一旦想要加上一个过滤器用来检测用户请求的数据时就会出现异常.   在过滤器中通过流读取出用 ...

  2. 使用gcc -g编译,gdb调试时仍然存在“no debug symbols found”的错误

    今天为调试一段代码,使用gcc将程序用-g选项重新编译.但是使用gdb进行debug时,仍然出现“no debug symbols found”的错误.仔细检查了一下Makefile,原来后面定义的连 ...

  3. webpack4.x加vue模板文件简单还原vue-cli

    1.首先 npm init -y 创建一个项目 2.安装vue npm install vue --save 3.然后安装webpack 注意如果全局没有还要安装全局的webpack和webpack- ...

  4. 与LCD_BPP相关的函数

    board/freescale/mx6q_sabresd/mx6q_sabresd.c:    panel_info.vl_bpix = LCD_BPP; common/lcd.c:   off  = ...

  5. luogu3809 后缀排序 后缀数组

    ref and 挑战程序设计竞赛. 主要是发现自己以前写得代码太难看而且忘光了,而且我字符串死活学不会啊,kmp这种东西我都觉得是省选+难度啊QAQ #include <iostream> ...

  6. Azure Storage Blob文件重命名

    Azure Storage的SDK并没有提供文件重命名的方法,而且从StorageExplorer管理工具里操作修改文件名的时候也有明确提示: 是通过复制当前文件并命名为新文件名再删除旧文件,不保存快 ...

  7. iOS第三方地图-高德地图(导航sdk路径规划)

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  8. win10安装virtualbox发生严重错误

    转载自:http://blog.csdn.net/ljw124213/article/details/50545101 Windows 10 系统在安装VirtualBox即将完毕时,突然回退,提示错 ...

  9. cf21D Traveling Graph

    You are given undirected weighted graph. Find the length of the shortest cycle which starts from the ...

  10. cf468B Two Sets

    Little X has n distinct integers: p1, p2, ..., pn. He wants to divide all of them into two sets A an ...