1、HashMap是线程不安全的,HashTable是线程安全的
- HashMap:Fail-fast 机制。表示快速失败,在集合遍历过程中,一旦发现容器中的数据被修改了,会立刻抛出ConcurrentModificationException异常,从而导致遍历失败,像这种情况:定义一个Map集合,使用Iterator迭代器进行数据遍历,在遍历过程中,对集合数据做变更时,就会发生Fail-fast。java.util包下的集合类都是快速失败机制的, 常见的的使用Fail-fast方式遍历的容器有HashMap和ArrayList等。
- HashTable:公开的方法比如get都使用了synchronized描述符。而遍历视图比如keySet都使用了Collections.synchronizedXXX进行了同步包装。并且是锁住全局的
Fail-fast底层实现:
迭代器在遍历集合的过程,会维护一个modCount变量。如果在遍历过程modCount发生变化,在迭代器使用hasNext/next遍历下一个元素的时候,都会检测modCount是否为expectedModCount的值,如果不是抛出异常。
2、由于线程安全,HashTable效率比不上HashMap
3、HashMap允许键为NULL,值为NULL。HashTable都不允许
HashMap是支持null键和null值的,而HashTable在遇到null时,会抛出NullPointerException异常。这并不是因为HashTable有什么特殊的实现层面的原因导致不能支持null键和null值,这仅仅是因为HashMap在实现时对null做了特殊处理,将null的hashCode值定为了0,从而将其存放在哈希表的第0个bucket中。
4、HashMap默认初始化数组大小是16,HashTable是11。HashMap扩容是扩大两倍,HashTable是两倍+1
5、HashMap不能直接使用hashCode计算下标,而是使用hashCode重新计算Hash值,再计算下标。HashTable使用的是hashCode计算下标(取mod)