JAVA面试题---------- Hashmap和Hashtable

1.Hashmap和Hashtable的区别

  • 都实现了Map接口

  • 平时用的多的是Hashmap,因为他效率高,方法没有加sychronaized关键字,所以是线程不安全的,在多线程的使用需要自己加同步。而Hashtable是线程安全的,方法都有同步,所以效率要慢一点

  • HashTable使用Enumeration,HashMap使用Iterator

  • Hashtable不允许 null 值(key 和 value 都不可以),HashMap允许 null 值(key和value都可以)

  • 实现机制不同

  • Hashmap源码分析:

首先我们知道刚入map的值是以一个条目放入,条目包括key,value,在map中自己定义这样一个条目类,里面有key和value属性还有一个int类型的hash值,我们放入元素的时候,如果key值相等,之前的key-->value条目就会被覆盖,判断key相等的方法就是比较当前要加入的entry的key的hash值,hash值相等,认为key重复,如果不重复,会根据计算得到的hash值给出entry的存放地址。


hashmap底层使用一个Entry数组实现的,每一个数值元素又是一个链表,当我们往HashMap中put元素的时候,先根据key的重新计算元素的hashCode,根据hashCode得到这个元素在table数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。往table数组中加入或者查找时,都是根据entry类型的元素的key的hash值进行操作的,这个table数组的初始长度是16,且必须是2的幂次数,扩容是扩为原始大小的2倍。后面会解释这样的原因。


    static final int DEFAULT_INITIAL_CAPACITY = 16;
    transient Entry[] table;

我们知道Object类中有一个hashCode()方法就是返回对象的hash值,但是并没有提供具体的实现,根据对象存放的地址给出hashcode值,那么其他要用hashcode解决冲突确定元素的存放地址的类需要自己提供实现方法,一般就是容器map,list,set中会利用hashcode操作元素的地址,那么为什么不用 Object.equals方法呢?

如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了,那么利用hashcode在集合查找时,就能大大降低对象比较次数,提高查找效率!


那hashmap是如何计算key的hash值的呢?在hashmap里就算hash的值是如下:


到hashcode值h,在找元素的存放地址,下图解释为什么要求table数组的初始长度是2的幂次


  • Hashtable源码分析: 

与hashmap不同的是初始容量

Hashtable中hash数组默认大小是11,增加的方式是 old*2+1

计算hashcode的方法不同,直接使用对象的hashcode(),也就是Object中的方法

猜你喜欢

转载自blog.csdn.net/wangdongli_1993/article/details/81099907