什么是Hashmap?
HashMap 是一个关联数组、哈希表,它是线程不安全的,允许key为null,value为null。遍历时无序。
在JDK8中,当链表长度达到8,会转化成红黑树,以提升它的查询、插入效率,它实现了Map<K,V>, Cloneable, Serializable
接口。
因其底层哈希桶的数据结构是数组,所以也会涉及到扩容的问题。
当HashMap的容量达到threshold
域值时,就会触发扩容。扩容前后,哈希桶的长度一定会是2的次方。
这样在根据key的hash值寻找对应的哈希桶时,可以用位运算替代取余操作,更加高效。
数组: 内存中的一片连续区域,同类型数据的集合,有索引,查询快,增删慢,不可扩容。
链表: 不连续的区域,每个节点放值和指向下一个节点的指针。查询慢,增删快
哈希表: 可以理解位数组和链表的组合。即一个一维数组,但是数组中的每个元素是一个链表
HashMap常量:
1.DEFAULT_INITIAL_CAPACITY //默认初始化的容量时16,必须是2的幂次方。
2.MAXIMUM_CAPACITY //最大容量:最大的容量是2^30。
3.DEFAULT_LOAD_FACTOR = 0.75f //默认的负载因子是0.75
4.TREEIFY_THRESHOLD = 8 //一个桶中bin的存储方式由链表转换成树的阈值。即当桶中bin的数量超过TREEIFY_THRESHOLD时使用树来代替链表。默认值是8
5.UNTREEIFY_THRESHOLD = 6 //当执行resize扩容操作时,当桶中bin的数量少于UNTREEIFY_THRESHOLD时使用链表来代替树。默认值是6 。
6.MIN_TREEIFY_CAPACITY //当桶中的bin被树化时最小的hash表容量
成员变量:
1.transient Node<K,V>[] table; //这个数组在首次使用时初始化,并根据需要调整大小。分配空间时,长度始终是2的幂次方。
- table是一个用于存放键值对的数组。
- 第一次使用(插入元素)时被初始化,根据需要可以重新分配空间(扩容: 因为规定容量是2的幂,所以扩容时把原容量乘2.)。
- 分配的空间长度必须是2的幂次方。
2.transient Set<Map.Entry<K,V>> entrySet; //当被调用entrySet时被赋值。通过keySet()方法可以得到Map中的key集合,通过values可以得到Map中的value集合。
3.transient int size; //该值用于存放Map中键值对的个数。
4.transient int modCount; //HashMap被结构性修改的次数
5.int threshold; //阈值,当HashMap中的键值对数量超过了阈值,就会扩容。thresold = capacity * loadFactor
6.final float loadFactor; //负载因子
HashMap共包括4个构造函数:
public HashMap()// 默认构造函
public HashMap(int initialCapacity, float loadFactor) / /指定“容量大小”和“加载因子”的构造函数
public HashMap(int initialCapacity) // 指定“容量大小”的构造函数
public HashMap(Map<? extends K, ? extends V> m) // 包含“子Map”的构造函数,将m中的全部元素逐个添加到HashMap中
哈希冲突的解决方法:1.开放地址法 2.链地址法 3.公共溢出法 4.再哈希法
为什么HashMap线程不安全?
HashMap会进行resize操作,在resize操作的时候会造成线程不安全。
1. put的时候导致的多线程数据不一致
2. HashMap的get操作可能因为resize而引起死循环
HashMap线程不安全应该怎么解决?
1.使用HashTable替代HashMap //一个线程访问HashTable的同步方法时,其他线程如果也要访问同步方法,会被阻塞住。
2.类ConcurrentHashMap定义Map //ConcurrentHashMap是JUC包中的一个类,方法内部使用了synchronized保证线程安全。
3.Collections类的synchronizedMap(Map m)方法可以返回一个线程安全的Map
HashMap跟Hashtable的区别?
HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,主 要区别在于 HashMap 允许空(null)键值(key),由于非线程安全,在只有一个线程访问 的情况下,效率要高于 Hashtable。
1.历史原因:Hashtable 是基于陈旧的 Dictionary 类的,HashMap 是 Java 1.2引进的 Map 接口的一个实现
2.同步性:Hashtable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的, 不是同步的
3.值:只有 HashMap 可以让你将空值作为一个表的条目的 key 或 value
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理