HashMap相关问题

1:HashMap和ConcurrentHashMap之间的区别:

  • JDK 1.7的HashMap和ConcurrentHashMap之间的区别见讲义
  • JDK1.8HashMap和ConcurrentHashMap之间的区别
  • HashMap:

    1. Java8 对 HashMap 进行了一些修改,最大的不同就是利用了红黑树,所以其由 数组+链表+红黑树 组成。
    2. Java7HashMap查找的时候,根据hash值能够快速定位到数组的具体下标,但是随后要顺序遍历链表,复杂度为O(n),Java8中当链表中元素超过8个以后,将;链表转换为红黑树,时间复杂度为O(logn)
    3. Java 7中是先扩容再添加新值,而Java 8是先增加新值再扩容
    4. Java7 中使用 Entry 来代表每个 HashMap 中的数据节点,Java8 中使用 Node,基本没有区别,都是 key,value,hash 和 next 这四个属性,不过,Node 只能用于链表的情况,红黑树的情况需要使用 TreeNode。我们根据存放在该位置的第一个节点的数据类型是Node还是TreeNode来判断是链表还是红黑树
get过程
  • 计算 key 的 hash 值,根据 hash 值找到对应数组下标: hash & (length-1)
  • 判断数组该位置处的元素是否刚好就是我们要找的,如果不是,走第三步
  • 判断该元素类型是否是 TreeNode,如果是,用红黑树的方法取数据,如果不是,走第四步
  • 遍历链表,直到找到相等(==或equals)的 key

  • ConcurrentHashMap

    1. Java 8中同样引入了红黑树
初始化过程


  • 这个初始化方法有点意思,通过提供初始容量,计算了 sizeCtl,sizeCtl = 【 (1.5 * initialCapacity + 1),然后向上取最近的 2 的 n 次方】。如 initialCapacity 为 10,那么得到 sizeCtl 为 16,如果 initialCapacity 为 11,得到 sizeCtl 为 32。
  • 初始化数组,也就是确定初始的容量,然后根据初始的容量来确定sizeCtl,并发问题通过对sizeCtl进行CAS操作
HashMap扩容为什么是原来的2倍
  • 在hashmap的源码中。put方法会调用indexFor(int h, int length)方法,这个方法主要是根据key的hash值找到这个entry在Hash表数组中的位置,源码如下: 

  • 上述代码也相当于对length求模。 注意最后return的是h&(length-1)。如果length不为2的幂,比如15。那么length-1的2进制就会变成1110。在h为随机数的情况下,和1110做&操作。尾数永远为0。那么0001、1001、1101等尾数为1的位置就永远不可能被entry占用。这样会造成浪费,不随机等问题。 length-1 二进制中为1的位数越多,那么分布就平均。
  • 扩容后,原来table[i]中的链表中所有节点分拆到新数组new Table[i]和new Table[i+oldLength]位置上

2:用自定义类型作为HashMap的key

  • 如果HashMap的key是自定义的类型,则需要重写equals()方法,因为对于创建的两个值一样的自定义类型的对象,如果不重写Object类的equals()方法,则由于这两个对象的地址不同,所以equals方法返回false,所以在hashmap中会认为这两个是不一样的两个键
  • 因此需要重写equals()方法,一旦重写了equals方法,则一定也要重写hashcode方法
  • 如果两个对象的equals()方法相等,则这两个对象一定有相等的hashcode,反之,两个对象有相同的hashcode不一定能说明这两个对象的equals()方法返回true
  • 当自定义类的多项式作为hashmap的key时,最好把这个类设计为不可变类,因为如果是可变对象的话,对象中的属性改变,则对象的hashcode也会相应的改变,导致下次无法查找到已存在Map中的数据,如果可变对象在HashMap中被用作键,那就要小心在改变对象状态的时候,不要改变它的hash值。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值