主体的区别:
HashTable是线程安全的-HashMap是线程不安全的,因为HashTable方法中都有sychronized关键字,HashMap在单线程中速度优于HashTable,,不过HashMap可以通过Collections.synchronizeMap(hashMap); 实现同步---所以个人认为HashMap完胜HashTable,而且jdk升级中HashMap做过多次性能优化
jdk1.5以上可以使用ConcurrentMap接口其实现类与Map的实现类相识,多了些原子性的操作方法,相当于Map的优化吧,尤其是ConcurrentHashMap(局部锁机制),它是HashTable的替代,比HashTable的扩展性、性能更好;
细节处理上的区别:
1. 在处理表的初始容量和负载因子上,HashTable处理上是:在构造器上硬加上了,默认capacity 11 loadfactor 0.75 || HashMap处理上:为默认的容量与负载因子单独分配一个空间,即:以常数的形式存在,便于理解和使用
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4 == 16 || static final float DEFAULT_LOAD_FACTOR = 0.75f
2.继承抽象类:HashTable继承已经被废弃的Dictionary并实现Map接口
HashMap继承AbstractMap同时实现Map,其实并不实现Map也不影响其的性能和功能
3.储存方式:HashMap采用数组+(链表+树) 表节点的树化和反树化(由树的数据结构转换为链表-链化)更加灵活,且性能提升
HashMap采用数组+链表
4.获取表的索引的算法:
HashMap->
通过KEY的-->static final int hash(Object key) --> (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);然后通过hash码对表的长度取模i = (n - 1) & hash
将高16位与低16为做异或处理可以极大的减少碰撞
HashTable->
通过KEY的--> key.hashCode();获取object原生的hashcode(其决定了hashtable的key不能为空)-->index = (hash & 0x7FFFFFFF) % tab.length;(将hashcode绝对值化然后对表的长度取模)
HashMap的获取索引方式经过处理能够有效的减少索引的耦合度,hashcode的碰撞
5.HashMap的成员变量无private修饰,并不是私有的,HashTable的成员变量是私有的。
6.允许为NULL的问题:
hashTable: 由于获取Key的hashcode时调用的是object默认的方法因此不能为空==》KEY不能为空,在Put()方法中可知value不能为空
hashMap:拥有自己获取KEY的Hashcode的方法,且可以为空,而且在Putval()方法中也没有不允许为空==》可以有一个key为空的Node,value可以为空