Java 面试题 HashMap、ConcurrentHashMap、HashTable

本文深入探讨HashMap的数据结构,包括其线程不安全性、允许null键值的特点,以及在JDK8中链表转红黑树的优化策略。分析了HashMap的底层实现,如哈希桶、扰动函数的作用,以及评估Hash算法的标准。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashMap

HashMap 是一个关联数组、哈希表,它是线程不安全的,允许key为null,value为null。遍历时无序。
其底层数据结构是数组称之为哈希桶,每个桶里面放的是链表,链表中的每个节点,就是哈希表中的每个元素。
在JDK8中,当链表长度达到8,会转化成红黑树,以提升它的查询、插入效率,它实现了Map<K,V>, Cloneable, Serializable接口。

hashcode,equals , ==

capacity、loadFactor、threshold、size概念

DEFAULT_LOAD_FACTOR = 0.75f;

源码

String中的hash()

public int hashCode() {
    int h = hash;
    if (h == 0 && count > 0) {
       int off = offset;
        char val[] = value;
        int len = count;
        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
       }
        hash = h;
   }
   return h;
}

h = R ∗ h + v a l [ o f f + + ] h = R * h + val[off++] h=Rh+val[off++]
其中R = 31,
R 为什么等于31

  1. 31是一个不大不小的奇素数,(偶数的hash效果都比较差)
  2. 31 * i == (i << 5) - i ,可以被JVM优化
  3. 哈希分布较为均匀

扰动函数

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

扰动函数就是为了解决hash碰撞的。它会综合hash值高位和低位的特征,并存放在低位,因此在与运算时,相当于高低位一起参与了运算,以减少hash碰撞的概率。(在JDK8之前,扰动函数会扰动四次,JDK8简化了这个操作)

如何评价Hash算法好坏?

  1. 尽可能分布均匀
  2. 效率尽可能快
MurMurHash
编译原理中如何完美hash

实现hash冲突的方式

  1. 拉链法
    1. 链表
    2. 红黑树
  2. 探测法

扩容

为什么要用2的幂指数倍数

##实现一个自定义的class作为HashMap的key该如何实现?

  1. 覆写hashCode以及equals方法应该遵循的原则
  2. Immutable

hash攻击

和hashtable 区别

  1. 与之相比HashTable是线程安全的,且不允许key、value是null。
  2. HashTable默认容量是11。
  3. HashTable是直接使用key的hashCode(key.hashCode())作为hash值,不像HashMap内部使用static final int hash(Object key)扰动函数对key的hashCode进行扰动后作为hash值。
  4. HashTable取哈希桶下标是直接用模运算%.(因为其默认容量也不是2的n次方。所以也无法用位运算替代模运算)
  5. 扩容时,新容量是原来的2倍+1。int newCapacity = (oldCapacity << 1) + 1;
  6. Hashtable是Dictionary的子类同时也实现了Map接口,HashMap是Map接口的一个实现类;

和concurrentHashMap区别

https://www.jianshu.com/p/7af5bb1b57e2
https://blog.csdn.net/zxt0601/article/details/77413921

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值