Java高级之HashMap中的哈希表

哈希表中的“表”

当我们需要存储一种映射数据时,就需要用到哈希表,也称为散列表(Hash Table)。

该数据结构中存储的是键(key)和值(value),它们是对应关系。

只需要给出一个指定的key,那么就能高效查找到它所匹配的值,效率非常高,时间复杂度接近于O(1)。

这就是哈希表中的“表”,表中维护了key与value的映射关系。

哈希表中的“哈希”

思考下,那么该如何存储键值对(key—value)呢?

如果使用链式存储结构:

肯定是不行的,因为如果要查找到指定key对应的结点,就需要遍历整个链表,时间复杂度很大,不是O(1)。

考虑使用顺序存储结构:

即使用数组,但数组只能根据下标,像a[0]、a[1]、a[2]这样来访问,但哈希表的key通常不是整数型,而多是字符串类型。

像a["key1"]、a["key2"]这样访问是无法的,语法不允许。

所以考虑通过一个中介,将key和数组下标进行转换,也是一种映射,来达到访问对应值value的目的,而具有这种转换能力的就叫做哈希函数。

Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。

这就是哈希表中的“哈希"。

在JDK1.8之前中HashMap使用的数组+链表结构。

在JDK1.8及之后中HashMap使用的数组+链表+红黑树结构。

哈希冲突

哈希冲突是发生在哈希表中插入新的键值对的时候。

像哈希表中添加键值对的步骤如下:

第一步:通过哈希函数,将key转换成数组下标。

第二步:如果数组下标位置没有元素,即为null,那么把该键值对添加到该位置。(在HashMap中使用Entry对象表示键值对)

但注意,数组的长度是有限的,当添加的元素越来越多,超过数组长度的时候,不同的key通过哈希函数获得的下标可能是相同的,但是在下标位置已经有元素了,那么这就发生了哈希冲突。

解决哈希冲突的方法有很多种,如开放寻址法、链表法(拉链法)。

在HashMap中就使用的是拉链法解决哈希冲突。

HashMap数组中每个元素都是一个Entry,同时是一个链表的头结点,Entry不仅保存了键和值

还有next指针,指向下一个结点。

 源码HashMap中的putVal方法有所说明:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值