关于hashmap里链表结构的疑问

luqing414 2017-08-24 04:01:29
刚看了帖子说hashmap里是hash表的结构,也可以理解为数组+链表,链表我看是存储这个key对应的所有数据,包括之前历史的数据,比如说先put(0, 1),完后put(0,2),那get的时候,虽然得到的是2,但之前的1还是存储在hashmap里,我想问下,这个历史的1存储还有什么意义,不是应该直接覆盖掉吗
...全文
452 7 打赏 收藏 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
luqing414 2017-08-25
  • 打赏
  • 举报
回复
引用 4 楼 luqing414 的回复:
[quote=引用 1 楼 maradona1984 的回复:] put(0, 1),完后put(0,2) 这个0这个key对应的entry的value指向会从1替换成2,不存在1还保存在map中的问题
看下这篇文章http://blog.csdn.net/zhangerqing/article/details/8193118 上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。如, 第一个键值对A进来,通过计算其key的hash得到的i=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其i也等于0,现在怎么办?HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,i也等于0,那么C.next = B,Entry[0] = C;这样我们发现i=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起,也就是说数组中存储的是最后插入的元素。 按他的说法,数组中是存的最后插入的元素,但是历史的元素都存链表了[/quote] 我又仔细看了下,我是不是该这样理解,它这个链表存的key的hash值相同的键值对,而不是key值相同的键值对,就是比如(0, 2), (16,3),这两个key分别为0和16,但是都存在下标为0的这个Entry的同一个链表上
luqing414 2017-08-25
  • 打赏
  • 举报
回复
引用 1 楼 maradona1984 的回复:
put(0, 1),完后put(0,2) 这个0这个key对应的entry的value指向会从1替换成2,不存在1还保存在map中的问题
看下这篇文章http://blog.csdn.net/zhangerqing/article/details/8193118 上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。如, 第一个键值对A进来,通过计算其key的hash得到的i=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其i也等于0,现在怎么办?HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,i也等于0,那么C.next = B,Entry[0] = C;这样我们发现i=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起,也就是说数组中存储的是最后插入的元素。 按他的说法,数组中是存的最后插入的元素,但是历史的元素都存链表了
Scaarf 2017-08-25
  • 打赏
  • 举报
回复
引用 2 楼 pany1209 的回复:
直接打开源码看一下put方法嘛。。。。
我想问一下,hashmap现在改成了数组+链表+红黑树,链表上节点数超过8就用红黑树,那超过部分形成的红黑树是存在数组的那个索引上?,不是已经存了链表么。。。。?难不成挂在链表上。。。。。。。?还是怎么放
lsongiu86 2017-08-25
  • 打赏
  • 举报
回复
这个地方说的是 两个对象 hashcode相同,equals 方法 不同的情形,hashcode 相同就会发生hash碰撞,但是equals方法不相等,就说明不是同一个对象,但是他们会放到同一个hashcode下面
pilnyun335857183 2017-08-25
  • 打赏
  • 举报
回复
hashmap中相同key多次put就是直接覆盖的,如果不覆盖旧值的话可以掉用putIfAbsent方法。这个看下源码中putVal的实现就明白了。 多个key hash碰撞后新增节点在链表中存放的位置是在链表尾端,4L理解有错哦;因为key hash碰撞的话也可能是相同key产生的,所以这时是需要遍历整个链表来判断是不是key已经存在;遍历完了新增节点顺手也就放在尾端了。 当数组中某个节点储存的链表长度达到8了,确实会将链表转化为红黑树,对应数组位置存放的是树的root,不贴代码了自己去看HashMap.treeifyBin方法实现吧。 (其实还要数组长度大于64才行;否则是执行resize,这个时候hashmap会扩大数组长度并重新计算node在数组上的位置使得node分布比较均匀,达到平均检索效率最高)
李德胜1995 2017-08-24
  • 打赏
  • 举报
回复
直接打开源码看一下put方法嘛。。。。
maradona1984 2017-08-24
  • 打赏
  • 举报
回复
put(0, 1),完后put(0,2) 这个0这个key对应的entry的value指向会从1替换成2,不存在1还保存在map中的问题

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧