HashMap常见面试题

Posted smallvampire

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap常见面试题相关的知识,希望对你有一定的参考价值。

1.HashMap底层是通过什么来实现的?

  在JDK1.7中是通过数组+链表来实现的;

  在JDK1.8中是通过数组+链表+红黑树来实现的

2.HashMap在JDK1.8中为什么使用红黑树?

  为了弥补JDK1.7中会出现的单链表过长(默认size超过8即转为红黑树,也可自己设置),导致查询效率低的问题,使用红黑树替代长链表,优化了插入和查询的效率

3.HasMap中如果哈希值冲突怎么办?

  (1).再散列法:再次进行计算哈希值;

  (2).链表法:使当前entry<k,v>.next指向冲突的值;

4.HashMap中初始化数组长度为多少?为什么要取2的幂次方大小呢?

  初始数组长度为大于当前key长度的最近2的幂次方值;

  通过源码可以发现,在计算出当前key的哈希值后,会进行当前数组长度(length-1)和key哈希值(已经处理过的hash值)的&计算,          所以可以得出只有取2的幂次方大小,才可以避免下标越界的发生。

/** h为计算后的hash值,length为当前数组长度 */
static int indexFor(int h,int lengh){
return h & (length-1);
}

5.HashMap中的key值可以为null吗?

  通过查看源码可知,在put方法中,有针对瑜key为空的判断,即可以为null

if(key==null)
    return putForNullKey(value);

  同时key为null的元素,其位置是固定的,在数组第一位(table[0]),所以意味着可以为null,但是只能有一个为null,而且table[0]只能存在一个value值,不能存储链表。

6.HashMap中插入数据时,在计算完key的hash值后,为什么还要再次进行异或运算才能得出最终hash值?

  为了避免出现大概率的hash值重复,所以通过右移、异或运算等操作对hash值进行再次计算,减小hash值冲突率,提高HashMap散列性,提高get方法效率

7.HashMap的扩容,是在插入数据前还是插入数据后进行扩容?

  JDK1.7:元素插入之前进行扩容

       JDK1.8: 元素插入之后进行扩容

8.HashMap扩容的条件是什么?

  JDK1.7:元素超了阈值,同时新放置的key的hash值没有重复

9.JDK1.7中多线程扩容HashMap有可能出现什么问题?

   陷入死循环,无限循环链表,占用cup100%

10.为什么在重写equals方法的时候也要重写hashcode方法?

  由于在重写equals方法时设置了比较的对象,所以需要对hashcode指定只针对该对象进行hash值编译,其它不进行equals的对象则不进行求取hash值。

public class MyMap {
    private String id;
    private String name;
    /** 
    * @Description: 只要id相同,则获取的value 值相同
    * @Param: [o] 
    * @return: boolean 
    * @Date: 2019-12-24 
    */ 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyMap myMap = (MyMap) o;
        return Objects.equals(id, myMap.id);
    }
    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

以上是关于HashMap常见面试题的主要内容,如果未能解决你的问题,请参考以下文章

HashMap常见面试题

JDK源码HashMap源码分析(附常见面试题)

Map集合的常见面试题

redis常见面试题

Java常见面试题分享

Java集合框架常见面试题