在HashMap中最重要的一个数据结构就是散列表,在散列表中又使用了红黑树和链表
散列表
散列表(Hash Table)又名哈希表/hash表,是根据键(key)直接访问在内存存储位置值(Value)的数据结构,他是由数组演化而来,利用数组支持按照下标进行随机访问的数据的特性
将Key映射为数组下标的函数叫做散列函数。可以表示为hashValue = hash(key);散列函数的基本要求:
- 散列函数计算得到的散列值必须是大于等于0的正整数,因为hashvalue需要作为数组的下标。
- 如果Key1 = Key2,那么经过hash后得到的哈希值必须相同:hash(key1) = hash(key2)
- 如果Key1 != Key2,那么经过hash后得到的哈希值必不相同:hash(key1) != hash(key2);(这一条都几乎不可能,像MD5、SHA等哈希算法也无法避免这种情况,这就是散列冲突)
散列冲突-链表法(拉链法解决发生冲突时问题)
在散列表中,数组的每个下标位置我们都可以称为桶(bucket)或者槽(slot),每个桶或者槽都会对应一条链表,所有散列值相同的元素我们都放到相同槽位的链表中。
散列冲突-链表法-时间复杂度分析
- 插入操作:通过散列函数计算出对应的散列槽位,将其插入到对应的链表中即可,插入的时间复杂度是O(1)
- 查找、删除操作:我们同样通过散列函数计算出对应的槽,然后遍历查找或者删除,平均情况下基于链表法解决冲突时查询的时间复杂度是O(1);当数据量够多,产生了较多的冲突时时间复杂度为O(n);冲突的数据量多时,链表数据结构转换为高效查找的红黑树,时间复杂度是O(logn)