学Java的都知道hashMap的底层是“链表散列”的数据结构也也可以说是hash表。在put的实话先根据key的hashcode重新计算hash值的,而我们又知道hash是一种算法。所以哈希码并不是完全唯一的。

查看哈希码百科:

http://kaigejava.com/article/detail/168

哈希表可以说就是数组链表,底层还是数组但是这个数组每一项就是一个链表

一:为什么说hashmap的put方法是根据key进行hashcode计算的呢?

查看源码:

在查看hash方法,如下:

查看putVal方法:

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,

boolean evict) {

Node [] tab; Node p; int n, i;

if ((tab = table) == null || (n = tab.length) == 0)

n = (tab = resize()).length;

if ((p = tab[i = (n - 1) & hash]) == null)

tab[i] = newNode(hash, key, value, null);

else {

Node e; K k;

if (p.hash == hash &&

((k = p.key) == key || (key != null && key.equals(k))))

e = p;

else if (p instanceof TreeNode)

e = ((TreeNode )p).putTreeVal(this, tab, hash, key, value);

else {

for (int binCount = 0; ; ++binCount) {

if ((e = p.next) == null) {

p.next = newNode(hash, key, value, null);

if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st

treeifyBin(tab, hash);

break;

}

if (e.hash == hash &&

((k = e.key) == key || (key != null && key.equals(k))))

break;

p = e;

}

}

if (e != null) { // existing mapping for key

V oldValue = e.value;

if (!onlyIfAbsent || oldValue == null)

e.value = value;

afterNodeAccess(e);

return oldValue;

}

}

++modCount;

if (++size > threshold)

resize();

afterNodeInsertion(evict);

return null;

}

二:hashmap怎么解决key的hash值冲突问题的?

上图是源码截图,说明:

1:初始化map的大小。默认是16

示例代码:HashMap map = new HashMap();

2:如果tab为空,就newNode一个放到链表中

示例代码:map.put("aa",1); 也就是图-1测试代码中的1

3:根据key算出的hash值如果存在,且key的值和map中已经存在的值equals了。所以就不处理。

如下图:

测试代码如图-1测试代码中的1和 2

4:如果p是TreeNode的子类进行putTreeValu

5:如果key的hash值和map中已经存在的key的hash相等且key不同的时候,如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。

如图-1测试代码 1和4中key的hesh值都为3104

图-1测试代码

在来看下Node这个内部类:

三:在来看看怎么get方法

说明:

1:如果链表中第一个值的hash值和需要获取的key的hash值相等的话,就直接取出。

2:如果链表first.next !=null就循环查找链表中的key,知道查询到key.equals(k) 取出对应的值。

查看源码或许感觉不懂,那么画图来说明:

总结:

数据结构:哈希表可以说就是数组链表,底层还是数组但是这个数组每一项就是一个链表。

map的put方法:

1:new hashMap的时候初始化默认大小为16

2:当map.put("aa",1)的时候判断map没有值,就把aa算的hash值放到0X004的位置

3:当再次执行map.put("aa",1)的是计算aa的hash值为3104.此时在OX004的位置已经有数据了。进行判断存在的key和新put的key是否相同。相同不处理,值覆盖

4:执行map.put("aa",2)的时候key和已经存在的key相同就直接覆盖value了

5:执行map.put(3104,"cc")的时候,key的hash值也为3104.此时数组中OX004已经存在数据,判断key是否相同。发现3104和aa不相同【注:此时就发生了hash冲突】,那么就aa这个链表前面追加3104

6:执行map.put("bb","cc")。假设bb计算出的hash值是3105就存放在了OX005上。

其他依次类推

map的get方法:

当执行map.get("bb")的时候先计算出bb的hash值为3105在对应的位置(也就是0X005)取出第一个判断值是不是bb如果是就直接取出value.

当执行map.get("aa")的时候先计算出aa的hash值为3104,去对应的位置取出判断值(3104)不等于(aa)且还有next。就循环取出进行比较。

http://kaigejava.com/article/detail/168

hashmap hash冲突怎么解决_hashMap怎么解决hash冲突的相关推荐

  1. hashmap hash冲突怎么解决_HashMap原理及冲突之简谈

    了解HashMap原理对于日后的缓存机制多少有些认识.在网络中也有很多方面的帖子,但是很多都是轻描淡写,很少有把握的比较准确的信息,在这里试着不妨说解一二. 对于HashMap主要以键值(key-va ...

  2. 解决哈希(hash)冲突的方法

    解决哈希(hash)冲突的方法 当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体取值时.冲突就难免会发生.另外,当关键字的实际取值大于哈希表的长度时,而且表中已装满了记录,如果插入一个新记 ...

  3. 分布式集群架构场景化解决⽅案(⼀致性Hash算法)

    什么是分布式和集群以及实现 主要内容 ⼀致性Hash算法 集群时钟同步配置 分布式ID解决⽅案 分布式调度问题 Session共享问题 分布式和集群是不⼀样的,分布式⼀定是集群,但是集群不⼀定是分布式 ...

  4. 解决jquery和prototype库冲突问题

    解决jquery和prototype库冲突问题 参考文章: (1)解决jquery和prototype库冲突问题 (2)https://www.cnblogs.com/Joanna-Yan/p/483 ...

  5. 解决transition动画与display冲突的几种方法

    解决transition动画与display冲突的几种方法 参考文章: (1)解决transition动画与display冲突的几种方法 (2)https://www.cnblogs.com/ihar ...

  6. 如何解决Git中的合并冲突

    如何解决Git中的合并冲突? #1楼 对于想要半手动解决合并冲突的Emacs用户: git diff --name-status --diff-filter=U 显示所有需要解决冲突的文件. 依次打开 ...

  7. n皇后问题(回溯法-递归法和循环法,最小冲突法(较快解决10000级别问题))

    文章目录 n皇后问题简单解释 递归版本 非递归版本-找到一个可行解版本 非递归版本-找到所有可行解版本 非递归版本二 最小冲突算法--5000级别较快 最小冲突算法改进 关于更高性能的算法 n皇后问题 ...

  8. 【vue.js开发】如何在vue里面优雅的解决跨域,路由冲突问题

    [vue.js开发]如何在vue里面优雅的解决跨域,路由冲突问题 当我们在路由里面配置成以下代理可以解决跨域问题 proxyTable: {'/goods/*': {target: 'http://l ...

  9. 创业冲突的五种解决方法是_当创业合伙人发生冲突时,最好的解决办法看这5招...

    原标题:当创业合伙人发生冲突时,最好的解决办法看这5招 小编今天与各位创业的合伙人和高管分享一位朋友的经历,然后根据其经历得出来的一篇文章:创业是一段漫长的旅程.现实中创业者往往会费尽力气,在茫茫人海 ...

最新文章

  1. mysql 锁测试_mysql行级锁测试 - echowu007的个人空间 - OSCHINA - 中文开源技术交流社区...
  2. Effective C++ 的52个条款列表
  3. 论文笔记-Augmented Lagrange Multiplier Method for Recovery of Low-Rank Matrices
  4. 20172332 2017-2018-2 《程序设计与数据结构》实验三报告
  5. HUD2795 线段树(单点更新)
  6. 【性能测试】性能测试工具选择
  7. SQL Server里查看当前连接的在线用户数
  8. golang和C的输出格式化对齐
  9. Jarvis Oj Pwn 学习笔记-level4
  10. 项目范围管理论文提纲
  11. 性能与实用兼具 Parallels Desktop 13 for Mac全球首发
  12. python中文版加密解密_python - 入门-对中英文加密解密
  13. 请给孩子多一点点空间
  14. cad转pdf格式怎么设置线宽
  15. Java Web应用开发
  16. Electron源码学习: Electron组成与初始化流程
  17. 基于SNMP的信息刺探扫描与防护策略
  18. 图的遍历算法-七巧板涂色
  19. 番外篇——直流电机桥源码分析LED驱动例程开发
  20. 2012-07-31

热门文章

  1. dev c++怎么设置断点_斑马进度计划软件可以检查计划中是否存在逻辑断点和错误逻辑关系...
  2. Excel导入30万条数据和导出50万条数据方案
  3. 关于Ubuntu与Debian的关系,了解!
  4. python中return true的用法_Return True/False何时使用它而不是Return
  5. 卡诺图与逻辑代数化简法
  6. [Django]MVT模式的详解
  7. EKF-SLAM simulated in MATLAB
  8. 阿里云王文彬:希望云计算支撑百亿设备
  9. 深圳 不是你呆的地方
  10. 移动端音视频从零到上手(推荐)