1.Hashcode和equals的区别?
Hashcode如果相等的情况下,对象的值不一定相等。equals比较对象的内容相同,hashcode一定相等。
2.为什么重写equals一定要重写hashcode?
因为遵循hashcode相等的情况下对象的值不一定相等。equals比较对象的内容相同,hashcode一定相等的原则,所以重写equals一定要重写hashcode保证原则不变。
3.HashMap和HashTable的区别?
1)线程安全上:HashMap是线程不安全的,HashTable被Synchronize修饰,所以线程安全
2)数据存储:HashMap运行数据的key为null,存放在数组的第0个位置。HashTable不允许数据为null,会抛出异常。
4.HashMap的put是如何实现的?
(1)计算key的hashCode
(2)将key的hashCode作为计算因子,通过哈希算法计算HashMap的数组下标index
(3)如果index下标的数组元素为空,直接put(新增元素)
(4)如果index下标的数组元素不为空,调用key的equal方法,判断index位置的链表是否存在
(5)如果找到链表中某个元素与key的equals方法相等,则使用value更新
(6)如果未找到链表中某个元素与key的equals方法相等,则新增
一般面试的时
候,经常会问到HashMap的原理。起初一直不理解,搞清楚HashMap的原理很重要吗?我就知道HashMap是线程不安全的。后来仔细看了下HashMap的底层实现原理,
原来HashMap既具有数组的快速查询,又兼具链表的快速插入特性。虽然不是线程安全的,但通过线程安全处理之后,无论是查询还是添加元素都很高效,用途广泛,因此掌握HashMap的底层原理的重要性不言而喻了。
5.如何理解hashcode的碰撞问题和解决方法?
对象值可能不等但是hashcode可能相等,即碰撞,如下图的例子中
String value1="a";
Integer value2=97;
System.out.println(value1.hashCode());
System.out.println(value2.hashCode());
System.out.println(value1.hashCode()==value2.hashCode());//结果为true
将所有关键字为同义词的记录存储在同一线性链表中。如下:
7.JDK1.8为什么引入红黑树?
Hashmap1.7采用数组+链表实现,采用HashEntry封装我们的键值对,Hashmap根据key查询没有冲突的情况下,时间复杂度为O(1),但是有冲突时时间复杂度为O(n),所以JDK1.8中,链表长度大于8,并且数组长度是64的情况下转为红黑树存放。
8.加载因子为什么是0.75不是其他?
Hashmap中jdk1.7的默认数组长度为16,加载因子为0.75,即当16x0.75=12时候开始扩容,扩容为原来的2倍(16x2=32)
如果加载因子太小,key的冲突概率会小,但是浪费内存空间
如果加载因子太大,key的冲突概率会大,但是利用的空间非常好
综上所述,空间利用率高,冲突概率低的情况下,取平衡值0.75