java经典面试题之hashmap

19 篇文章 1 订阅

经典面试题总结:

  • hashmap具备哪些特点?

  • Java7和Java8的区别?

  • 哈希表如何解决Hash冲突?

  • 为什么 HashMap 中 String、Integer 这样的包装类适合作为 key 键

  • HashMap 中的 key若 Object类型, 则需实现哪些方法?

  • hash的计算规则?

  • 默认初始化大小是多少?为啥是这么多?为啥大小都是2的幂?

  • 为什么会选择8作为链表转红黑树的阈值?

 

面试题解析:

hashmap具备那些特点?

Java7和Java8的区别?

jdk7 数组+单链表 jdk8 数组+(单链表+红黑树)

jdk7 链表头插 jdk8 链表尾插 

    头插: resize后transfer数据时不需要遍历链表到尾部再插入   

    头插: 最近put的可能等下就被get,头插遍历到链表头就匹配到了

    头插: resize后链表可能倒序; 并发resize可能产生循环链

jdk7 先扩容再put jdk8 先put再扩容 (why?有什么区别吗?)

jdk7 计算hash运算多 jdk8 计算hash运算少(http://www.jasongj.com/java/concurrenthashmap/#寻址方式-1)

jdk7 受rehash影响 jdk8 调整后是(原位置)or(原位置+旧容量)

 

 哈希表如何解决Hash冲突?

这里写图片描述

 

 为什么 HashMap 中 String、Integer 这样的包装类适合作为 key 键

这里写图片描述

HashMap 中的 key若 Object类型, 则需实现哪些方法?

这里写图片描述

hash计算规则

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

取出key的hashcode,右移16位,然后取异或  : int是4个字节,也就是32位,我们右移16位也即是把高位的数据右移到低位的16位,然后做异或,那就是把高位和低位的数据进行重合,同时保留了低位和高位的信息

 

默认初始化大小是多少?为啥是这么多?为啥大小都是2的幂?

初始化大小为1<<4, resize时扩容为原来的两倍;

 HashMap的容量为什么是2的n次幂,和这个(n - 1) & hash的计算方法有着千丝万缕的关系,符号&是按位与的计算,这是位运算,计算机能直接运算,特别高效,按位与&的计算方法是,只有当对应位置的数据都为1时,运算结果也为1,当HashMap的容量是2的n次幂时,(n-1)的2进制也就是1111111***111这样形式的,这样与添加元素的hash值进行位运算时,能够充分的散列,使得添加的元素均匀分布在HashMap的每个位置上,减少hash碰撞。

 

为什么会选择8作为链表转红黑树的阈值?
根据泊松分布,在负载因子默认为0.75的时候,单个hash槽内元素个数为8的概率小于百万分之一,所以将7作为一个分水岭,等于7的时候不转换,大于等于8的时候才进行转换,小于等于6的时候就化为链表。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值