我们先看2个类的定义

view plaincopy to clipboardprint?
public class Hashtable        
        extends Dictionary        
        implements Map, Cloneable, java.io.Serializable    

public class Hashtable
        extends Dictionary
        implements Map, Cloneable, java.io.Serializable
view plaincopy to clipboardprint?
public class HashMap        
        extends AbstractMap        
        implements Map, Cloneable, Serializable    

public class HashMap
        extends AbstractMap
        implements Map, Cloneable, Serializable可见Hashtable 继承自 Dictiionary 而 HashMap继承自AbstractMap

Hashtable的put方法如下

view plaincopy to clipboardprint?
public synchronized V put(K key, V value) {    //###### 注意这里1        
    // Make sure the value is not null        
    if (value == null) { //###### 注意这里 2        
        throw new NullPointerException();        
    }        
    // Makes sure the key is not already in the hashtable.        
    Entry tab[] = table;        
    int hash = key.hashCode(); //###### 注意这里 3        
    int index = (hash & 0x7FFFFFFF) % tab.length;        
    for (Entry e = tab[index]; e != null; e = e.next) {        
        if ((e.hash == hash) && e.key.equals(key)) {        
            V old = e.value;        
            e.value = value;        
            return old;        
        }        
    }        
    modCount++;        
    if (count >= threshold) {        
        // Rehash the table if the threshold is exceeded        
        rehash();        
        tab = table;        
        index = (hash & 0x7FFFFFFF) % tab.length;        
    }        
    // Creates the new entry.        
    Entry e = tab[index];        
    tab[index] = new Entry(hash, key, value, e);        
    count++;        
    return null;        
}    

    public synchronized V put(K key, V value) {    //###### 注意这里1
        // Make sure the value is not null
        if (value == null) { //###### 注意这里 2
            throw new NullPointerException();
        }
        // Makes sure the key is not already in the hashtable.
        Entry tab[] = table;
        int hash = key.hashCode(); //###### 注意这里 3
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry e = tab[index]; e != null; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                V old = e.value;
                e.value = value;
                return old;
            }
        }
        modCount++;
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();
            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
        }
        // Creates the new entry.
        Entry e = tab[index];
        tab[index] = new Entry(hash, key, value, e);
        count++;
        return null;
    }注意1 方法是同步的
注意2 方法不允许value==null
注意3 方法调用了key的hashCode方法,如果key==null,会抛出空指针异常 HashMap的put方法如下
view plaincopy to clipboardprint?
public V put(K key, V value) { //###### 注意这里 1        
    if (key == null)    //###### 注意这里 2        
        return putForNullKey(value);        
    int hash = hash(key.hashCode());        
    int i = indexFor(hash, table.length);        
    for (Entry 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;        
}    

    public V put(K key, V value) { //###### 注意这里 1
        if (key == null)    //###### 注意这里 2
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry 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;
    }注意1 方法是非同步的
注意2 方法允许key==null
注意3 方法并没有对value进行任何调用,所以允许为null    

补充:    
Hashtable 有一个 contains方法,容易引起误会,所以在HashMap里面已经去掉了
当然,2个类都用containsKey和containsValue方法。    

结论: ashMap 在大多数情况下是优先选择的。