HashMap深度解析:面试必备知识点

2 下载量 22 浏览量 更新于2024-08-03 收藏 40KB MD 举报
HashMap 概述 HashMap 是 Java 中的一个集合类,属于 Map 接口的实现,它允许存储键值对,其中键是唯一的。HashMap 提供了快速的查找、添加和删除操作,平均时间复杂度为 O(1)。它通过哈希算法来定位数据,将键映射到数组的特定位置,以便快速访问。 HashMap 和 HashTable 的区别 相同点:HashMap 和 HashTable 都实现了 Map 接口,用于存储键值对,都使用哈希表作为底层数据结构。 不同点: 1. 线程安全性:HashMap 非线程安全,而 HashTable 是线程安全的,因此在多线程环境下,HashTable 更安全,但性能更低。 2. null 值支持:HashMap 允许键和值为 null,而 HashTable 不允许。 3. 处理冲突的方式:两者都使用链地址法解决哈希冲突,但 HashMap 在 1.8 版本后采用了红黑树优化,当链表长度超过一定阈值(8)时会转换为红黑树,提高查找效率。 4. 性能:由于线程安全的实现,HashTable 的性能通常低于 HashMap。 HashMap 和 HashSet 的区别 HashMap 存储键值对,而 HashSet 存储单个对象。HashSet 内部同样基于 HashMap 实现,其键就是存储的对象,值则是固定的 NULL。 HashMap 底层结构 HashMap 基于一个动态增长的数组和链表(或红黑树)实现。在 Java 1.7 中,当发生哈希冲突时,数据存储在链表中;从 Java 1.8 开始,如果链表长度达到 8,会将链表转换为红黑树,以优化查找性能。 重要内部类和接口: 1. Node 接口:HashMap 中的节点,存储键值对,包含键、值、哈希值和指向下一个节点的引用。 2. KeySet 内部类:表示 HashMap 中所有键的集合,提供了迭代器以便遍历键。 3. Values 内部类:表示 HashMap 中所有值的集合,同样提供迭代器遍历值。 4. EntrySet 内部类:表示 HashMap 中所有键值对的集合,用于遍历键值对。 HashMap 的关键属性: - loadFactor:装载因子,控制何时进行扩容,默认为 0.75。 - threshold:扩容阈值,为 loadFactor * capacity。 - initialCapacity:初始容量,初始化 HashMap 时设定的大小。 HashMap 构造函数: 允许指定初始容量和装载因子,如果不指定,则使用默认值。 HashMap put 的全过程: 1. 计算键的哈希值。 2. 根据哈希值确定数组索引位置。 3. 如果该位置没有节点,直接插入新节点。 4. 如果有节点,进行链表或红黑树查找,若找到相同键,则替换旧值,否则插入新节点。 5. 当负载因子达到阈值时,进行扩容。 扩容机制: 当 HashMap 中的元素数量达到容量的 loadFactor 倍时,会进行扩容,新的容量是原来的两倍。 get 方法全过程: 1. 计算键的哈希值。 2. 根据哈希值找到对应的数组索引。 3. 通过链表或红黑树查找对应的节点。 4. 返回节点中的值。 HashMap 的遍历方式: 主要有三种遍历方式:通过 keySet()、values() 和 entrySet() 迭代器分别遍历键、值和键值对。 HashMap 中的移除方法: 根据键来移除键值对,首先计算键的哈希值,然后在对应索引处找到节点并删除。 面试题可能涉及: 1. HashMap 的数据结构和扩容策略。 2. 线程不安全的原因。 3. 哈希碰撞的处理。 4. get 方法的实现原理。 5. HashMap 与 Hashtable、ConcurrentHashMap 的区别。 了解以上内容后,你将能够更深入地理解 HashMap,并在面试中自信地讨论这个主题。