java HashMap相关

java中HashMap是使用最多的数据结构之一,也是面试java基础必问的问题之一。它有以下特性:
(1) 一般情况下查找的时间为O(1),特殊情况下为O(n) (jdk7)
(2) 存储键值对(键是唯一的)
(3) 不支持并发

一、数据结构

为了实现特性(1),HashMap使用了由数组和链表组成的hash表,这样在查找的时候根据key的hashCode值找到对应的桶(数组所在的下标),然后遍历桶找到对应的元素(key的equals())

HashMap结构图

当HashMap中的元素到达一定数量时,为了满足条件(1),需要进行扩容。为了明确扩容的条件,引入了装载因子(loadFactor),当size > capacity * loadFactor时进行扩容(resize)。但这解决不了HashMap最坏情况下查找变为O(n),当元素key的hashCode都相同,插入的数据就都在同一个桶里面,此时HashMap退化为LinkList,在自定义对象的时候应该注意hashCode的定义。

二、循环链表

HashMap中的元素个数大于规定的阈值时,就会进行扩容,重新hash,并分配到相应的桶

    Entry<K,V> next = e.next;
    int i = indexFor(e.hash, newCapacity);
    e.next = newTable[i];
    newTable[i] = e;
    e = next;

在单线程情况下重新resize分配的过程如下:

单线程resize过程
在多线程情况下,resize过程容易出现环,下面就上图例子说明多线程情况下环形成的过程。
场景:两个线程同执行HashMap扩容操作
条件:当Thread1线程执行到上面代码片的第一行,cpu被另Thread2线程占用且执行完扩容操作,此时Thread1看到的HashMap数据结构为下图所示,接着Thread1继续执行扩容操作
多线程resize
结果:Thread1执行完毕,形成了如下图所示的环
HashMap resize形成环过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值