1. 程式人生 > >HashTable與HashMap的區別,結源碼分析

HashTable與HashMap的區別,結源碼分析

log code length dex needed 源碼分析 not null 下使用 value

一、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。

  

HashTable與HashMap的區別,結源碼分析