Java集合-HashMap常见问题

版权声明:fangwh https://blog.csdn.net/qq_40804005/article/details/82192363

本文主要围绕HashMap集合常见问题做一个总结
参考链接:
https://blog.csdn.net/song19890528/article/details/16891015
(HashMap原理)
https://www.jianshu.com/p/b40fd341711e

1.HashMap与Hashtable的区别?

HashMap可以接受null键值和值,而Hashtable则不能。
Hashtable是线程安全的,通过synchronized实现线程同步;而HashMap是非线程安全的,但是速度比Hashtable快。

2.当两个对象的hashcode相同怎么办?

当哈希地址冲突时,HashMap采用了链地址法的解决方式,将所有哈希地址冲突的记录存储在同一个线性链表中。具体来说就是根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。

3.如果两个键的hashcode相同,你如何获取值对象?

HashMap在链表中存储的是键值对,找到哈希地址位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象。

4.如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办?

HashMap默认的负载因子大小为0.75,也就是说,当一个map填满了75%的空间的时候,和其它集合类(如ArrayList等)一样,将会创建原来HashMap大小的两倍的数组,来重新调整map的大小,并将原来的对象放入新的数组中。

5.为什么String, Interger这样的wrapper(包装)类适合作为键?

String, Interger这样的wrapper类是final类型的,具有不可变性,而且已经重写了equals()和hashCode()方法了。其他的wrapper类也有这个特点。不可变性是必要的,因为为了要计算hashCode(),就要防止键值改变,如果键值在放入时和获取时返回不同的hashcode的话,那么就不能从HashMap中找到你想要的对象。作为不可变类天生是线程安全的,而且可以很好的优化比如可以缓存hash值,避免重复计算等。

6.ConcurrentHashMap和Hashtable的区别?

Hashtable和ConcurrentHashMap有什么分别呢?它们都可以用于多线程的环境,但是当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。因为ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,而其它的线程不需要等到迭代完成才能访问map。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。

7.HashMap的遍历?

第一种:(效率高,使用此种方式)

Map map = new HashMap();
        Iterator iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            Object key = entry.getKey();
            Object val = entry.getValue();
        }

第二种:(效率低,以后尽量少使用)

Map map = new HashMap();
        Iterator iter = map.keySet().iterator();
        while (iter.hasNext()) {
            Object key = iter.next();
            Object val = map.get(key);
        }

HashMap这两种遍历方法是分别对keyset及entryset来进行遍历,但是对于keySet其实是遍历了2次,一次是转为iterator,一次就从hashmap中取出key所对于的value。而entryset只是遍历了第一次,它把key和value都放到了entry中,即键值对,所以就快了。

8.如果让你实现一个自定义的class作为HashMap的key该如何实现?

用自定义类作为key,必须重写equals()和hashCode()方法。

猜你喜欢

转载自blog.csdn.net/qq_40804005/article/details/82192363