目录
1.equals和hashCode的区别
hashCode是本地方法,如果在没有从重写的情况下,调用方法得到对象的内存地址
equals是成员方法,在没有重写的情况下,它的实现为this == obj,比较的是本类和参数对象的内存地址
2. 重写equals为什么要重写hashCode
理解这个问题,我们首先来看一下jdk源码,尝试从中解决问题
我们要遵循equals相等,hashCode一定相等的规范,如果重写了equals方法,就需要重写hashcode从而实现如上规范。
3.HashMap 与HashTable的区别
hashMap线程不安全,HashTable的方法都是sychornized修饰的,所以hashTable线程安全
hashMap效率较高,hashTable效率较低
hashMap允许key为空,存放在数组的第0个位置,hashTable不允许key为空,会报空指针异常
4.hashMap底层原理,put方法的实现
Node<key,value>,hashmap的底层实现原理是在jdk8及以后为数组+链表+红黑树,
- hashmap调用put方法时,首先根据Key两次hash运算,得到数组的下标
- 如果数组对应下标的链表为空,把Node插入链表的第一位
- 如果链表不为空,Node的key对链表节点的key比较,如果key相同,直接覆盖,如果不相同就插入(插入或删除就是在维护一颗红黑树或有序链表)
- 如果链表的长度大于等于八,链表自动调整为红黑树。为什么是8,前人的经验之谈,如果有更好的实践证明,可能会是别的数值。
hashmap的底层实现原理在dk7和jdk7之前的实现原理为数组+链表
节点为Entry,实现过程同上,但是没有红黑树的操作,链表维护的的是有序链表
5.如何理解hashCode碰撞问题
hashcode是由key通过hash函数运算f()得到的,如果不同的key得到相同的f(key),那么我们就称发生了hashcode碰撞,也可以称为冲突。
常见的解决方法有,开放地址法,再散列函数法,链地址法(hashMap使用的就是这个),公共溢出区法
6.hashMap为什么要引入红黑树
红黑树:是一颗近似平衡的二叉搜索树,但是它比AVL树的旋转操作,耗时更短。
再jdk7以及7之前,查询的时间复杂度:
- 没有发生hash冲突:
o(1)
- 发生hash冲突:
o(n)
jdk8引入红黑树之后,查询的时间复杂度:
- 没有发生时间复杂度:
o(1)
- 发生hash冲突:
o(logn)
可以看出,在引入红黑树的数据结构之后,查询效率提升了不少。
7.加载因子为什么是0.75
小问题:hashmap提前放入1万条数据,插入与读取如何是最优的?
HashMap中的数组默认的容量为16,容量大于等于容量的0.75倍时,进行扩容。对数组容量扩容两倍,原来容量16现在容量为32
加载因子为0.75是官方测试出来的数据,效果是最优的。加载因子太小的情况下,冲突概率比较小,但是非常浪费空间,而且非常频繁的扩容。
加载因子太大的晴空下,占用空间小,但是冲突概率大