hashmap 获取key不区分大小写_面试系列 HashMap

HashMap在Java中是基于哈希表的数据结构,它允许null键值对,但不是线程安全的。HashMap使用链地址法解决哈希冲突,JDK1.8引入了红黑树以优化性能。HashMap的容量是2的幂次方,以优化哈希算法和减少扩容成本。当链表长度超过8时,链表会转换为红黑树。HashMap在多线程环境下不安全,推荐使用ConcurrentHashMap。HashMap的get和put过程涉及到哈希计算、链表遍历或红黑树查找。扩容时,旧链表会使用尾插法重新插入新数组,以避免JDK1.7头插法可能导致的环形链表问题。
摘要由CSDN通过智能技术生成

首先你肯定是要先介绍一下hashmap是什么

介绍

数据结构部分

  • 键值都允许null
  • 非线程安全
  • 它的key是无序的。

HashMap的数据结构是什么?(HashMap如何解决哈希冲突,还有什么方法)

这个问题可以从两个方面来解释

数据底层具体存储的是什么:HashMap是一个用来存储Key-Value的键值对集合,Java中HashMap采用了链地址法。链地址法,简单来说,就是数组加链表的结合。每个数组元素都是一个链表结构,当数据被Hash后,得到数组下标,把数据放在对应下标元素的链表上。所以它底层的数据结构是数组+链表,JDK1.8增加了红黑树部分。链表的每一个节点都会保存自身的hash、key、value、以及下个节点地址

这样的存储方式有什么优点:Hash解决冲突的办法主要有两种类型:

一是封闭散列,比如开放地址法:基本思想是所有的记录都存储在数组中,当在p位置发生哈希冲突时,会以p位置为基准通过探测序列找到一个不冲突的哈希地址。

它的优点在于,如果记录总数可以预知,可以创建完美哈希函数,此时处理数据的效率是非常高的。它的缺点很明显,1.扩容效率低会导致某次操作的时间成本飙升2.删除时只能在删除的节点上做标记,而不能真正删除节点,,因为如果删除节点,会导致与该位置冲突的后续节点无法查询。总的来说就是对于频繁插入和删除的操作比较复杂和耗时。

二是开放散列,链地址法:基本思想就是数组加链表的结合。每个数组元素都是一个链表结构,当数据被Hash后,得到数组下标,把数据放在对应下标元素的链表上。

它的优点在于对于记录总数频繁可变的情况,处理的比较好,删除记录时,比较方便,直接通过指针操作即可。它的缺点在于哈希表的跳转访问会带来额外的时间开销,JDK1.8之后引入了引入了红黑树,当链表长度太长(默认超过8)时,链表就转换为红黑树,利用红黑树快速增删改查的特点提高HashMap的性能。

主要参数

  • Node<K,V>[] table:初始化长度length(默认值是16)
  • loadFactor:负载因子(默认值0.75)
  • threshold:是HashMap所能容纳的最大数据量的Node(键值对)个数。threshold = length * Load factor。也就是说,在数组定义好长度之后,负载因子越大,所能容纳的键值对个数越多。
  • size:HashMap中实际存在的键值对数量。(与table的长度区分)

为什么是16?

我觉得应该是一个经验值,它在源码中的表示是写成1左移运算符4,而不是16我觉得就是一种提示,只要是2次幂,其实用 8 和 32 都差不多。

Hash算法(hashmap 长度2的幂次方原因

java中建议初始化hashmap的时候设置一个尽量接近真实情况的二次幂方。这有两个原因:

  1. java会根据用户传入的容量值,通过计算,得到第一个比他大的2的幂。直接给一个二次方会节省这个计算搜索时间
  2. 避免不必要的扩容过程

这与hashmap的定位算法相关。

hash算法的目标是元素位置尽量分布均匀,尽量避免发生哈希冲突。

return (key == null) ? 0 : (h = key.hashCode()) ^ (h &g
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值