面试题[HashMap]

HashMap的特性

HashMap存储的是键值对 值允许为null  key值不可重复  如果重复 value将被覆盖

非同步 线程不安全 无序

底层原理

jdk8后采用的是:数组+链表+红黑树

当使用put方法时,会先对key做一个hashcode值计算,找到在bucket数组中的位置,来存储Entry对象;如果hashcode值相同就通过equals方法进行比较;如果equals方法返回false,就将数据以链表的形式存储在数组对应的位置,并将之前在该位置的数据往链表的后面移动(头插法),并记录一个next属性,来指示后移的那个数据。

当使用get方法时,同上

头插法

HashMap会将Entry对象不断插入链表的头部,这样也防止来尾遍历,否则Entry每次添加还要定位到尾节点。如果条件竞争(多线程操作),可能会出现环形链表,当使用get操作时,有可能发生死循环。

put方法如何实现

1.计算key的hashcode值

2.如果散列表为空的时候,调用resize()方法初始化散列表

3.如果么有发生碰撞 直接将元素添加到散列表

4.如果发生了hah碰撞,进行判断 如果key值相同 替换value值 如果是 链表的结构 在链表的尾部进行插入,如果链表个数达到红黑树的阈值8   转为黑树结构  如果是红黑树结构  调用树的插入方法

5.如果元素总数大于阈值 就会调用resize()方法进行扩容

扩容实现resize()方法

默认负载因子大小为0.75,当一个map填满75%的bucket时,将会创建原HashMap2倍大小的bucket,并将原来的对象重新计算放入新的bucket中。

哈希碰撞

key值不同  但是通过hashCode计算的值却是一样,,,发生碰撞以后  HashMap使用LinkedList来存储对象(键值对)

为什么引入红黑树

jdk1.8以前  数据结构是数组 +链表

当hashMap中大量的数据都存放到一个桶里的话  这个通就会很大  时间遍历的复杂度是0(0) 针对这种问题 引入了红黑树来优化

为什么String integre这样的wrapper类适合的作为主键

String是不可变得类  String/Integre都重写了hashCode和equals方法 。如果使用对象的话  就需要再重写其hashCode方法和equals方法 并且这个对象是不可变的。。

发布了62 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_37876078/article/details/105715174
今日推荐