首页 > 技术文章 > HashTable与HashMap的区别,结源码分析

houstao 2018-01-13 10:27 原文

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

 

  

推荐阅读