java HashMap

HashMap

  • HashMap底层是使用数组+链表的形式进行存储,数组作为主干,链表作为hash冲突后的解决方案。
  • 加入数据的时候会用hashCode()和特定的算法算出对应的位置,如果对应的位置上已经有值,则通过equal()比较,如果不同则放入到链表中。每一对值都是一个Entry。
  • 如果容量超过阈值(容量*负载因子)将会重新创建数组,同时将老数组的数据进行拷贝(拷贝过程中会重新计算位置)
  • hashMap的长度为2的幂次,主要是为了保证计算出的序号均匀
int index = (n - 1) & hash;//n为容量,eg:16-1=》1111

https://www.cnblogs.com/chengxiao/p/6059914.html hashmap的原理,为什么容器的长度是2的幂次,为什么要重写hashcode()
https://blog.youkuaiyun.com/zjcjava/article/details/78495416长度为什么为2的幂次建议参考这篇文章

  • 重写hashCode()和equals() compareTo()
    • 如果不重写equals(),比较的将是两个对象的地址
    • 如果不重写hashCode(),默认是地址。否则创建两个参数完全相同的对象,在hash数据结构中存放的位置将不同,将不能定位到同样的位置
    • hashCode()并不是一定要重写,但是用到hash数据结构时一定要
    • 但是重写hashCode()方法的时候一定要保证equals()返回的结果一致
    • 有序容器(TreeSet)重写compareTo()
    • 当然你自己定义的对象可以实现equals相同而hashCode不同,但java的Object类中规定相同的对象一定要有相同的hashCode
    • 对象被存储到hash表中,变量不能改变,因为改变后虽然hashcode发生了变化,但是不会重新计算位置
    • hashCode()不能使用随机数,hash值必须稳定,同一个对象hashcode值始终相同

https://www.cnblogs.com/happyPawpaw/p/3744971.html
https://www.cnblogs.com/kanliwei/p/4280425.html

  • 在jdk8中,当冲突的节点数量超过8个后,将改用红黑树进行存储
    • 但是并不要求像TreeSet那样一定要实现Comparable,不过实现了效率更高。(如果没有实现会调用System.identityHashCode(),效率较低)

    是否需要实现Comparable:https://blog.youkuaiyun.com/zly9923218/article/details/51656920

http://www.importnew.com/23164.html

  • 添加数据时可能触发resize()操作,而多个线程同时进行put操作的时候,可能会同时resize(),resize()操作会重新计算元素存放位置,之前存放在同一位置的一批数据在重新计算后后可能还在一个链中(但是顺序翻转),因此并发过程可能造成循环引用,从而在get()这个位置的数据时无限循环。建议使用ConcurrentHashMap解决
  • 多线程下put()操作,如果有hash碰撞,执行addEntry(hash, key, value, i),多个线程的i值相同,先加入的就可能会数据丢失

http://www.cnblogs.com/binyue/p/3726403.html

  • equals()和hashCode()间存在一个约定,两个元素相同则hashcode也要相同

保证容器的线程安全

  • 使用Hashtable、或者是synchronized、或者是Collections.synchronizedMap进行粗粒度的线程安全保护
  • 选择并发包进行细粒度的并发控制:ConcurrentHashMap,CopyOnWriteArrayList,ArrayBlockingQueue,SynchronousQuene

ConcurrentHashMap

  • 引入了分段锁,在每次进行操作的时候存在风险的位置都会添加上锁,保证并发情况下不会有问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值