关于面试常问HashMap的问题
1.jdk1.7和1.8HashMap有什么区别?
区别:
JDK1.7下:
1)底层所采用的是数组加链表的结构
2)采用头插法
3)扩容方式:直接用其hash值和需要扩容的二进制数进行&(这里的扩容时必须是2的幂次方,因为只有这样其二进制的最后一位才会是1,用来减少哈希冲突),(hash&table.length-1),另其是在插入后进行扩容
4)会先对数组进行初始化,然后进行put
jdk1.8:
1)底层采用的是数组+链表+红黑树,当链表长度大于8并且数组长度大于64时,会形成红黑树。
红黑树的特点:
每个节点只有两种颜色,红色或是黑色,根节点必须为黑
每个叶子结点都是黑色的空结点
从根结点到叶子结点时不能出现两个连续的红色结点
从任意结点出发,到它下边的子结点的路径包=包含的黑色结点数目相同
2)采用尾插法,原因是在JDK1.7时单链表进行的纵向延伸,当采用头插法时会容易出现逆序且环形链表死循环问题,而1.8下的尾插法可以解决这个问题
3)扩容方式:计算hash的方法yuJDK1.7有所不同,另其是在插入前进行扩容
4)会先进行put方法,如哦没有初始化,则在put方法内进行初始化
2.说说HashMap的扩容过程
HashMap只有在内部数组无法装载更多对象时,即size>threshold时需要对数组进行二倍扩容。
对原数组中的数据进行重新rehash。
rehash的结果,该值在原数组和新数组的位置相同或该值在新数组中的位置等于该值在原数组中的位置加上原数组的长度。
3.HashMap中可以使用自定义类型作为其key和value吗?
可以
如果是自定义的比较器时需要重写equals()方法和hashCode()方法。
4.HashMap与HashTable的区别和联系?
相同点:
都实现了Map接口,保存了Key-Value(键值对)
不同点:
1.HashMap继承AbstractMap类,而HashTable继承Dictionary类。
2.HashMap是线程不安全的,是非Synchronize(同步)的,而HashTable是线程安全的,是Synchronize的。
3.HashTable中key和value都不允许为null,HashMap中空值可以作为Key,也可以有一个/多个Key的值为空值。
4.HashMap的hash数组默认长度大小为16,扩容方式为2的指数,HashTable的hash数组默认长度大小为11,扩容方式为两倍加一。
5.HashMap与HashTable相同点和不同点
相同点:
都实现了Map接口,保存了Key-Value(键值对)
不同点:
1.HashMap继承AbstractMap类,而HashTable继承Dictionary类。
2.HashMap是线程不安全的,是非Synchronize(同步)的,而HashTable是线程安全的,是Synchronize的。
3.HashTable中key和value都不允许为null,HashMap中空值可以作为Key,也可以有一个/多个Key的值为空值。
4.HashMap的hash数组默认长度大小为16,扩容方式为2的指数,HashTable的hash数组默认长度大小为11,扩容方式为两倍加一。
- HashMap和TreeMap的相同点和不同点
相同点:
1)HashMap(JDK1.8下)和TreeMap都是基于数组加链表实现的
2)HashMap和TreeMap都是非线程安全的
不同点:
1)HashMap继承于抽象类AbstractMap,并且实现Map接口,TreeMap实现SortedMap接口
2)HashMap遍历时,取得的数据完全是随机的,TreeMap默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的
3)HashMap添加、删除操作时间复杂度都是O(1),TreeMap添加、删除操作时间复杂度都是O(log(n))
4)HashMap最多只允许一条key为Null,允许多条value为Null,TreeMap只允许value为Null,key不能为Null
居中的图片:
暂时想到就这么多,以后再补充吧