一、HashTable
首先看一下官网的推荐
1 * Java Collections Framework</a>. Unlike the new collection 2 * implementations, {@code Hashtable} is synchronized. If a 3 * thread-safe implementation is not needed, it is recommended to use 4 * {@link HashMap} in place of {@code Hashtable}. If a thread-safe 5 * highly-concurrent implementation is desired, then it is recommended 6 * to use {@link java.util.concurrent.ConcurrentHashMap} in place of 7 * {@code Hashtable}.
解释一下上面的话,主要是说hashtable是线程安全,如果是你是在线程非安全的情况下使用的话,推荐使用hashMap,如果在线程安全的情况下使用的话,推荐使用ConcurrentHashMap来替代HashTable。言外之意也就是说hashTable已经过时,最好不要使用。既然已经弃用,我们简单地额讲解一下。
线程安全
Java源码:
1 /** 2 * Maps the specified <code>key</code> to the specified 3 * <code>value</code> in this hashtable. Neither the key nor the 4 * value can be <code>null</code>. <p> 5 * 6 * The value can be retrieved by calling the <code>get</code> method 7 * with a key that is equal to the original key. 8 * 9 * @param key the hashtable key 10 * @param value the value 11 * @return the previous value of the specified key in this hashtable, 12 * or <code>null</code> if it did not have one 13 * @exception NullPointerException if the key or value is 14 * <code>null</code> 15 * @see Object#equals(Object) 16 * @see #get(Object) 17 */ 18 public synchronized V put(K key, V value) { 19 // Make sure the value is not null 20 if (value == null) { 21 throw new NullPointerException(); 22 } 23 24 // Makes sure the key is not already in the hashtable. 25 Entry tab[] = table; 26 int hash = hash(key); 27 int index = (hash & 0x7FFFFFFF) % tab.length; 28 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) { 29 if ((e.hash == hash) && e.key.equals(key)) { 30 V old = e.value; 31 e.value = value; 32 return old; 33 } 34 } 35 36 modCount++; 37 if (count >= threshold) { 38 // Rehash the table if the threshold is exceeded 39 rehash(); 40 41 tab = table; 42 hash = hash(key); 43 index = (hash & 0x7FFFFFFF) % tab.length; 44 } 45 46 // Creates the new entry. 47 Entry<K,V> e = tab[index]; 48 tab[index] = new Entry<>(hash, key, value, e); 49 count++; 50 return null; 51 }
1 /** 2 * Returns the value to which the specified key is mapped, 3 * or {@code null} if this map contains no mapping for the key. 4 * 5 * <p>More formally, if this map contains a mapping from a key 6 * {@code k} to a value {@code v} such that {@code (key.equals(k))}, 7 * then this method returns {@code v}; otherwise it returns 8 * {@code null}. (There can be at most one such mapping.) 9 * 10 * @param key the key whose associated value is to be returned 11 * @return the value to which the specified key is mapped, or 12 * {@code null} if this map contains no mapping for the key 13 * @throws NullPointerException if the specified key is null 14 * @see #put(Object, Object) 15 */ 16 public synchronized V get(Object key) { 17 Entry tab[] = table; 18 int hash = hash(key); 19 int index = (hash & 0x7FFFFFFF) % tab.length; 20 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) { 21 if ((e.hash == hash) && e.key.equals(key)) { 22 return e.value; 23 } 24 } 25 return null; 26 }
解析:你会看到HashTable的每个方法前面都添加了一个synchronized的锁,说明HashTable是线程安全的,我们的上一篇已经很详细的讲解了HashMap,是非线程安全,这里不再具体讲解。另外你也会发现HashTable在求数组的index下标的时候是使用的%,而HashMap使用的&,这李是没有优化的。
是否为空
当我们在使用put的时候,从上面的代码你会发现,HashTable的key和value是不能为空的,否则会NullPointerException。