HashMap是Hashtable的轻量级实现(非线程安全的实现)。 1、HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。(HashMap以null作为key时,总是存储在table数组的第一个节点上) 2、HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 3、Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
4、两者最主要的区别在于Hashtable是线程安全,而HashMap则非线程安全。Hashtable的实现方法里面都添加了synchronized关键字来确保线程同步,因此相对而言HashMap性能会高一些,我们平时使用时若无特殊需求建议使用HashMap,在多线程环境下若使用HashMap需要使用Collections.synchronizedMap()方法来获取一个线程安全的集合。Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 5、HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75。HashMap扩容时是当前容量翻倍即:capacity2,Hashtable扩容时是容量翻倍 1即:capacity2 1。 6、Hashtable计算hash是直接使用key的hashcode对table数组的长度直接进行取模; HashMap计算hash对key的hashcode进行了二次hash,以获得更好的散列值,然后对table数组长度取摸。
代码语言:javascript复制int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
代码语言:javascript复制int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
return h & (length-1);