HashMap集合笔记

HashMap数据结构:
底层数据结构由数组和链表构成的,数组其实是HashMap的主体,链表则是为了解决Hash冲突而存在的。
java8以后链表长度超过8会自动转成红黑树。

HashMap主干为一个Entry数组,其中的key-value都是Map.Entry中的属性。将key的值进行hash之后进行存储,即每一个key都是计算hash值,然后再存储。每一个Hash值对应一个数组下标,数组下标是根据hash值%数组长度计算得出。而每个Entry存放着一个键值对和同时指向另一个Entry的引用,如果发生哈希冲突,该引用即指向另一个Entry。

如果发生哈希冲突是怎么找到正确的值?
hashMap基于hashing的原理,通过put和get方法进行存取数据,当使用put方法传递键值得时候,调用键对象hashCode 方法计算hashcode,然后找到哈希桶的位置来存储对象,当发生哈希碰撞的时候(不同的键却产生了相同的hashCode),对象将会存储同一个哈希桶中链表的头节点。同样取值的时候也是先通过调用键的hashcode方法计算hashcode,然后找到hash桶位置(实际上就是找到存储值的那个单项链表),然后在通过键的equals方法来找到桶中正确的键值。

HashMap的线程安全性:
不安全。
HashMap底层是一个Entry数组,当发生hash冲突的时候,hashMap是采用链表的方式来解决的,在对应的数组位置存放 链表的头结点。对链表而言,新加入的节点会从头结点加入,多线程情况下此时如果2个键一样hashCode的进行添加,数据 就会丢失。

HashMap怎么解决线程安全:
1.java.util.Collections.SynchronizedMap
但是它所有方法都是带同步对象锁的,和 Hashtabe一样,它不是性能最优的。
2.并发包:java.util.ConcurrentHashMap
底层采用分段锁的技术,将数据分段存储,然后给每一个段数据一把锁,线程占用锁访问其中一个段数据的时候,其他的线程可以访问别的段数据。也就是说ConcurrentHashMap的主干是个Segment数组,每个Segment下是hashEntry或者是它的一个链表,上锁只是锁的一个Segment,所以他相对前2种直接锁整个表,速度要快。

HashMap的扩容方式和扩容时机:
1.HashMap使用的是懒加载,构造完HashMap对象后,只要不进行put 方法插入元素之前, HashMap并不会去初始化或者扩容table。第一次调用put方法时,发现table为空会调用resize方法 则会开始第一次初始化扩容,默认长度为16。
2.扩容因子为0.75超过后,扩容倍数为2。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值