面试官:小伙子,你能给我说一下HashMap的实现原理吗?

1. HashMap概述:

HashMap是基于哈希表的Map接口的非同步实现(他与Hashtable类似,但Hashtable是线程安全的,所以是同步的实现),此实现提供可选的映射操作,允许使用null值和null键,但他并非有序。

2. HashMap数据结构与实现原理:

在jdk1.7和jdk1.8中,HashMap的数据结构是有所差别的,进行一些优化来解决冲突问题,下面我们就分别从两个版本的角度来分析一下他的改动与区别

(一)jdk1.7版本

在jdk1.7版本的时候采用的是数组+链表的形式,也就是采用了拉链法。

将哈希冲突值加入到每个数组的链表中,他的插入采用的是头插法的形式(这种方法最大的弊端就是会使插入值产生环,从而无限循环,后面我们将详细讲解这种方法的弊端操作),在进行hash值计算的时候,jdk1.7则采用的是9次扰动(4次位运算+5次异或运算)的方式进行处理(因为本人目前暂时用的jdk1.8所以无法利用源码进行讲解,望见谅),除此之外在扩容上也有所不同,在jdk1.7中采用的全部按照原来的方式进行计算(即hashCode ->> 扰动函数 ->> (h&length-1)),而在jdk1.8中则采用按照扩容后的规律计算(即扩容后的位置=原位置 or 原位置 + 旧容量),下面让我们来详细讲解一下jdk1.8。

(二)jdk1.8版本

而jdk1.8的版本则采用数组+链表+红黑树的方式,如下图:

这种方法可以大大优化了哈希冲突的问题,减少了搜索时间,当添加的数目达到阈值的时候可以将链表转换为红黑树的形式,而当红黑树的节点小于6的时候就会从红黑树转化为链表的形式(如果不理解红黑树的话,可以参考我的上一篇文章),而在进行插入值的时候则采用的是尾插法的形式,这种方法解决了成环的情况发生

 final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值