HashMap与HashTable的区别

来源:互联网 发布:梦幻西游特色知乎 编辑:程序博客网 时间:2024/06/03 17:47

1、HashMap是非线程安全的,Hashtable是线程安全的

HashMap是非线程安全的,同一时间可以有多个线程进行写操作。如果需要满足线程安全,可以用Collections.synchronizedMap()是HashMap具有线程安全的能力或者直接使用ConcurrentHashMap类。

.

Hashtable是一个遗留类,除了构造方法以外所有的public方法都用了synchronized关键字修饰,由于不用开关同步锁,HashMap的效率比HashTable高。对比同样实现了线程安全的ConcurrentHashMap,ConcurrentHashMap中引入了分段锁,并发性比HashTable高。


2、HashMap的key和value都允许null值存在,Hashtable则会抛出异常


HashMap允许最多一个key为null,允许多个value为null。当HashMap调用put时key为null时,会调用putForNullKey()方法。该方法在不同版本有不同的实现方式。


HashMapput()

public V put(K key, V value) {      /*  如果key值为null,调用putForNullKey,不同版本该方法的实现也不同,         1.该方法将从头遍历table数组,将key为null的键值对放在数组中第一个为空的地方。         2.用中间变量标记null 键值对。*/      if (key == null)          return putForNullKey(value);      //key不为null时,计算当前key的hash值。      int hash = hash(key.hashCode());      //计算该hash值对应的数组下标i      int i = indexFor(hash, table.length);      /*  遍历table[i]中的Entry链表,如果不存在hash值相同的键值对,直接插入数组,         如果存在hash值相同的键值对,比较两个键值对的key,如果key相同,用当前键值对覆盖此键值对,         如果key不同,直接插入。      */      for (Entry<K,V> e = table[i]; e != null; e = e.next) {          Object k;          if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {              V oldValue = e.value;              e.value = value;              e.recordAccess(this);              return oldValue;          }      }      modCount++;      addEntry(hash, key, value, i);      return null;  }  



而HashTable的put方法在检测到null值时会抛出异常:


Hashtableput()

 public synchronized V put(K key, V value) {        if (key == null) {            throw new NullPointerException("key == null");        } else if (value == null) {            throw new NullPointerException("value == null");        }        ……    }