集合框架:Map

本文详细介绍了HashMap的数据结构与工作原理,包括其内部Node类、哈希算法、扩容机制以及线程不安全性。同时,对比分析了ConcurrentHashMap的线程安全实现,JDK1.7中的锁分离技术和JDK1.8的CAS操作。还提到了HashSet、HashTable及LinkedHashMap的特点。
摘要由CSDN通过智能技术生成

Map:

    HashMap时使用频率较高的用于映射处理(键值对)的数据类型,底层数据结构是由"数组+链表+红黑树"组成,初始化大小为16,它根据键的hashCode值来存储数据,大多数情况下可以直接定位到它的值,因而具有较高的访问速度,遍历顺序是不确定的;同时允许多个线程同时操作,可能导致数据不一致,线程不安全,可以使用Collections的synchronizedMap()方法使其具有线程安全的能力,或者使用ConcurrentHashMap;

    HashMap解释:

    它包含一个Node的内部类,该内部类实现了Map.Entry接口,本质上是一个映射(键值对),HashMap使用哈希表来进行存储,系统调用key的hashCode()方法得到一个hashCode值,然后通过hash算法的后两部运算(高位运算和取模运算)来定位该键值对的存储位置,当两个key的hashCode值相同时,表示发生了Hash碰撞,使用更好的Hash算法和扩容机制来解决Hash碰撞,它的初始容量默认为16(所能容纳的最大的Node个数),负载因子默认为0.75,当超过负载因子*初始化长度时会进行扩容,扩容默认为当前容量的两倍(先判断扩容前数组是否需要扩容,需要扩容创建一个新的数组,将原有数组内容转移到新数组中);

关于JDK1.8将hashCode异或其右移十六位:优化了高位运算的算法,通过高十六位或低十六位实现,可以再数组table的length比较小的时候也能保证高低Bit都参与Hash计算中,同时不会有太大的开销;

关于hash值要与length-1相比:把hash值对数组长度进行取模运算消耗大,没有位运算快.当length总是2的n次方时&符号运算等价于取模运算,但是具有更高的效率;

关于数组长度时2的幂次方:便于使用&进行类似取模运算,在h的二进制与操作效率会变快,空间也不会浪费;

关于为什么不直接用红黑树而是用链表转红黑树:当元素小于八个时链表结构能保证查询性能,链表搜索时间复杂度时O(n),当元素大于八个时,红黑树需要进行左旋,右旋,变色操作来保持平衡,搜索时间复杂度是O(logn),红黑树也会提高查询效率,但是新增节点的效率会下降;

关于负载因子为0.75:它只是一个相对于时间效率和空间效率的一个平衡选择,一般不会做出改变;

ConcurrentHashMap解释:

JDK1.7中:保证线程安全的原因在于使用了锁分离技术,使用多个锁来控制对Hash表的不同部分进行修改,使用多个锁控制对hash表的不同部分进行修改,内部使用段(Segment)来表示这些不同的部分,初始化默认值为16,如果操作发生在多个不同的段上就可以并发进行;

JDK1.8中:摒弃了段的概念,并发控制使用Synchronized和CAS来操作;

HahsSet解释:

底层使用HashMap存储数据,所有操作都是调用HashMap相关方法完成,区别是元素无序,不能重复添加,只能包含一个为null的值;

HashTable解释:

基于Dictionary类,HashMap是基于Map接口的实现;经过Synchronized修饰,线程安全;

LinkedHashMap解释:

集成HashMap,它包含的散列表是双向列表,因此在散列表元素比较多的情况下,查找和删除效率更高;

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值