HashMap的数据结构

目录

一、HashMap底层实现原理

二、HashMap底层数据结构的组成

Ⅰ一个键值对是如何存入数组中的

Ⅱ一个键值对是如何存入链表或红黑树中的

三、链表和红黑树的用途

Ⅰ 链表的主要用途

Ⅱ红黑树的主要用途

四、链表和红黑树的转换方式

Ⅰ将一个红黑树转换成列表

Ⅱ将一个链表转换成红黑树


一、HashMap底层实现原理

        HashMap是基于哈希表的Map接口的非同步实现。元素以键值对的形式存放,并且允许null键和null值,因为key值唯一(不能重复),因此,null键只有一个。另外,HashMap不保证元素存储顺序,是一种无序的,和放入的顺序并不相同(此类不保证映射的顺序,特别是它不保证该顺序恒久不变)。

       哈希表由一个数组和指向该数组的指针组成。数组中的每个元素称为桶,每个桶都可以存储一个键值对。

  •         当新增一个元素时,HashMap 首先对 key 值进行哈希函数计算,得到一个桶的索引,然后将键值对存储到该桶中。
  •         在查找元素时,同样先通过哈希函数计算出键所属的桶,然后在该桶中查找是否存在该键的值。如果存在,则返回其对应的值,否则返回 null。
  •         当多个键映射到同一个桶时,HashMap 使用链表来处理冲突,即在该桶中维护一个链表,将哈希值相同的键值对插入到链表中。在 Java 8 中,当链表中元素个数超过一定阈值(默认为 8),该链表会被转化为红黑树来提高查找效率。当链表元素个数变少时,又会被转化回链表。

         HashMap是线程不安全的。

二、HashMap底层数据结构的组成

       HashMap底层数据结构主要由数组和链表(或红黑树)组成。

        具体来说,HashMap内部维护了一个数组,数组元素是一个个的Entry对象。Entry对象中包含了键值对的信息,即key和value,以及一个next指针,指向下一个Entry对象,从而形成一个链表。当链表长度大于8时,会将链表转成红黑树,以提高查找效率。

        使用哈希算法来确定键值对在数组中的位置,具体来说,将key的hashCode()取模数组长度,得到的值就是该键值对在数组中的下标。如果不同的key计算出的hashCode()模数组长度后得到的下标相同,就会产生哈希冲突,这时候就在该下标对应的链表中进行查找,找到对应的key值。

        通过哈希算法和链表(或红黑树)的结合,HashMap可以实现高效的键值对存储和查找。

Ⅰ一个键值对是如何存入数组中的

        键值对一般是通过对象的方式存储在数组中。可以创建一个对象,对象的属性名为键,属性值为值,然后将这个对象存储在数组中。例如,以下代码将一个键值对 `{ name: "Tom", age: 18 }` 存储在一个数组中:

let arr = [];
let obj = { name: "Tom", age: 318};
arr.push(obj);

        现在,这个数组 arr 中就包含了一个对象,对象的属性名为 'name',属性值为 "John",属性名为 'age',属性值为 '30'。我们可以通过访问数组中的对象来获得这个键值对的值,例如:

console.log(arr[0].name);
console.log(arr[0].age);

Ⅱ一个键值对是如何存入链表或红黑树中的

        在Java中,键值对通常是通过Map接口实现的。Map接口有多个实现,如HashMap、LinkedHashMap、TreeMap等,它们有不同的数据结构来存储键值对。

        对于HashMap,当添加键值对时,会先根据键的HashCode值来确定要存储的位置(桶)。如果该位置已经有其他键值对存在,则以链表的形式将新的键值对连接在已有的键值对后面。如果链表长度达到一定的阈值,会将链表转换为红黑树进行存储。这样可以提高查找、插入、删除等操作的效率。

三、链表和红黑树的用途

        链表和红黑树都是常用的数据结构,它们的用途各有不同。

Ⅰ 链表的主要用途

        链表的主要用途是表示线性结构,可以用来实现队列、栈、链表等数据结构。

        链表的优点是插入和删除操作非常快,因为只需要改变指针的指向,不需要移动其他元素。

        缺点是访问元素的时间复杂度是O(n),不适合用于查找和排序。

Ⅱ红黑树的主要用途

        红黑树是一种平衡二叉搜索树,可以用于实现有序集合、有序映射等数据结构。

        红黑树的优点是插入、删除、查找的时间复杂度都是O(log n),可以保证树的平衡性,避免了二叉搜索树退化成链表的问题。

        缺点是实现比较复杂,需要维护红黑树的性质。

  • 综上所述,链表和红黑树都有各自的优点和局限性,应根据具体场景选择合适的数据结构。

四、链表和红黑树的转换方式

Ⅰ将一个红黑树转换成列表

        将一个红黑树转换成链表可以使用中序遍历的方式,即从小到大遍历树的所有节点,将节点依次连接起来形成链表。具体步骤如下:

  1.  对于红黑树的每个节点,先将其左子树转换成链表。
  2.  找到当前节点的前驱节点(即左子树的最右节点),将其与当前节点连接起来,成为当前节点的后继节点。
  3.  将当前节点的右子树转换成链表。
  4.  继续处理当前节点的后继节点,重复步骤2至步骤4,直到处理完整个树。
  •         最终形成的链表顺序为从小到大排列。

Ⅱ将一个链表转换成红黑树

        将一个链表转换成红黑树,可以使用递归的方法,具体步骤如下:

  1. 找到链表的中间节点,作为当前子树的根节点。
  2. 递归处理链表的左半部分,作为当前节点的左子树。
  3. 递归处理链表的右半部分,作为当前节点的右子树。
  4. 根据红黑树的性质,需要对新建的节点进行颜色调整、旋转等操作,以保证红黑树的平衡性和性质。
  •         最终形成的红黑树具有平衡性和性质,可以高效地进行搜索、插入和删除操作。

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值