HashMap与Hashtable的异同点

HashMap与Hashtable的异同点

  • Hashtable继承自Dictionary, HashMap继承自AbstractMap

    // Hashtable继承自Dictionary类
    public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V> {
    }
    // HashMap继承自AbstractMap
    public class HashMap<K, V> extends AbstractMap<K, V>{
    }
    
    // AbstractMap实现了Map接口
    public abstract class AbstractMap<K, V> implements Map<K, V> {
    }
  • Hashtable是线程安全的,效率低; HashMap是线程不安全的,效率高。如果jdk版本高于1.5,多线程环境中建议使用ConcurrentHashMap

    //Hashtable的put方法签名有synchronized
    public synchronized V put(K key, V value) {
    }
    //HashMap的put方法签名没有synchronized
    public V put(K key, V value) {
    }
    // 给未同步的HashMap进行同步
    Map hashMap = new HashMap();
    Map m = Collections.synchronizeMap(hashMap);
  • Hashtable的key和value都不允许为null;HashMap最多允许1个null值的key,n多个null的value。

    // Hashtable
    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");
        }
        // ...
    }
    //HashMap, 方法允许key==null, 方法并没有对value进行任何调用,所以允许为null
    public V put(K key, V value) {
        if (key == null) {
            return putValueForNullKey(value);
        }
    }
  • HashMap把Hashtable的contains()方法去掉了,改成containsvalue()和containsKey()。因为contains()方法容易让人引起误解。

     /** 
       * Returns true if this Hashtable contains the specified object as
       * the value of at least one of the key/value pairs.
       */
    
      public boolean contains(Object value) {
            return containsValue(value);
      } 
  • HashMap的Iterator迭代器是fail-fast迭代器,而Hashtable的Enumeration迭代器不是fail-fast的。
    所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。

你可能感兴趣的:(Java基础)