HashMap与HashTable主要区别

Map接口源代码如下:

public interface Map<K,V> {

   boolean containsKey(Object key);

   boolean containsValue(Object value);

   V get(Object key);

   V put(K key, V value);

   V remove(Object key);



   // @param m mappings to be stored in this map.

   void putAll(Map<? extends K, ? extends V> m);



   void clear();



   // @return a set view of the keys contained in this map.

   Set<K> keySet();



   Collection<V> values();



   // @return a set view of the mappings contained in this map.

   Set<Map.Entry<K, V>> entrySet();



   boolean equals(Object o);

   int hashCode();



   interface Entry<K,V> {

       K getKey();

       V getValue();

       V setValue(V value);

       boolean equals(Object o);

       int hashCode();

   }

}



          

   

   

AbstractMap源代码如下:

public abstract class AbstractMap<K,V> implements Map<K,V> {

   

    protected AbstractMap() { }



    public int size() {

        return entrySet().size();

    }



    public boolean isEmpty() {

        return size() == 0;

    }



    /**

     * This implementation iterates over entrySet searching

     * for an entry with the specified value.  If such an entry is found,

     * true is returned.  If the iteration terminates without

     * finding such an entry, false is returned.  Note that this

     * implementation requires linear time in the size of the map.

     *

     * @throws ClassCastException 

     * @throws NullPointerException 

     */

    public boolean containsValue(Object value) {

        Iterator<Entry<K,V>> i = entrySet().iterator();

        if (value==null) {

            while (i.hasNext()) {

                Entry<K,V> e = i.next();

                if (e.getValue()==null)

                    return true;

            }

        } else {

            while (i.hasNext()) {

                Entry<K,V> e = i.next();

                if (value.equals(e.getValue()))

                    return true;

            }

        }

        return false;

    }



    /**

     *This implementation iterates over entrySet() searching

     * for an entry with the specified key.  If such an entry is found,

     * true is returned.  If the iteration terminates without

     * finding such an entry, false is returned.  Note that this

     * implementation requires linear time in the size of the map; many

     * implementations will override this method.

     *

     * @throws ClassCastException   

     * @throws NullPointerException

     */

    public boolean containsKey(Object key) {

        Iterator<Map.Entry<K,V>> i = entrySet().iterator();

        if (key==null) {

            while (i.hasNext()) {

                Entry<K,V> e = i.next();

                if (e.getKey()==null)

                    return true;

            }

        } else {

            while (i.hasNext()) {

                Entry<K,V> e = i.next();

                if (key.equals(e.getKey()))

                    return true;

            }

        }

        return false;

    }



    /**

     *This implementation iterates over entrySetsearching

     * for an entry with the specified key.  If such an entry is found,

     * the entry's value is returned.  If the iteration terminates without

     * finding such an entry, null is returned.  Note that this

     * implementation requires linear time in the size of the map; many

     * implementations will override this method.

     *

     * @throws ClassCastException          

     * @throws NullPointerException       

     */

    public V get(Object key) {

        Iterator<Entry<K,V>> i = entrySet().iterator();

        if (key==null) {

            while (i.hasNext()) {

                Entry<K,V> e = i.next();

                if (e.getKey()==null)

                    return e.getValue();

            }

        } else {

            while (i.hasNext()) {

                Entry<K,V> e = i.next();

                if (key.equals(e.getKey()))

                    return e.getValue();

            }

        }

        return null;

    }





    // Modification Operations



    /**

     * <p>This implementation always throws an

     * UnsupportedOperationException.

     *

     * @throws UnsupportedOperationException 

     * @throws ClassCastException         

     * @throws NullPointerException

     * @throws IllegalArgumentException     

     */

    public V put(K key, V value) {

        throw new UnsupportedOperationException();

    }



    /**

     * This implementation iterates over entrySet() searching for an

     * entry with the specified key.  If such an entry is found, its value is

     * obtained with its getValue operation, the entry is removed

     * from the collection (and the backing map) with the iterator's

     * remove operation, and the saved value is returned.  If the

     * iteration terminates without finding such an entry, null is

     * returned.  Note that this implementation requires linear time in the

     * size of the map; many implementations will override this method.

     *

     * <p>Note that this implementation throws an

     * UnsupportedOperationException if the entrySet

     * iterator does not support the remove method and this map

     * contains a mapping for the specified key.

     *

     * @throws UnsupportedOperationException 

     * @throws ClassCastException     

     * @throws NullPointerException       

     */

    public V remove(Object key) {

        Iterator<Entry<K,V>> i = entrySet().iterator();

        Entry<K,V> correctEntry = null;

        if (key==null) {

            while (correctEntry==null && i.hasNext()) {

                Entry<K,V> e = i.next();

                if (e.getKey()==null)

                    correctEntry = e;

            }

        } else {

            while (correctEntry==null && i.hasNext()) {

                Entry<K,V> e = i.next();

                if (key.equals(e.getKey()))

                    correctEntry = e;

            }

        }



        V oldValue = null;

        if (correctEntry !=null) {

            oldValue = correctEntry.getValue();

            i.remove();

        }

        return oldValue;

    }





    // Bulk Operations



    /**

     * This implementation iterates over the specified map's

     * entrySet() collection, and calls this map's put

     * operation once for each entry returned by the iteration.

     *

     * Note that this implementation throws an

     * UnsupportedOperationException if this map does not support

     * the put operation and the specified map is nonempty.

     *

     * @throws UnsupportedOperationException 

     * @throws ClassCastException    

     * @throws NullPointerException         

     * @throws IllegalArgumentException    

     */

    public void putAll(Map<? extends K, ? extends V> m) {

        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())

            put(e.getKey(), e.getValue());

    }



    /**

     * This implementation calls entrySet().clear().

     *

     * Note that this implementation throws an

     * UnsupportedOperationException if the entrySet

     * does not support the clear operation.

     *

     * @throws UnsupportedOperationException 

     */

    public void clear() {

        entrySet().clear();

    }

    ..............

 }

HashMap源代码如下:

public class HashMap<K,V>

    extends AbstractMap<K,V>

    implements Map<K,V>, Cloneable, Serializable

{  .........  }

Hashtable的源代码如下:

public class Hashtable<K,V>

    extends Dictionary<K,V>

    implements Map<K,V>, Cloneable, java.io.Serializable {



    /**

     * The hash table data.

     */

    private transient Entry<K,V>[] table;



    /**

     * The total number of entries in the hash table.

     */

    private transient int count;

    

    .............

}

 HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable。可能你觉得HashTable很好用,为什么不用呢?这里简单分析他们的区别。

1.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:
Map Collections.synchronizedMap(Map m),这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。

2.HashTable不允许null值(key和value都不可以),在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。

3.HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样。

4.HashTable使用Enumeration,HashMap使用Iterator。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。

以上只是表面的不同,它们的实现也有很大的不同。

5.HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

6.哈希值的使用不同,HashTable直接使用对象的hashCode,代码是这样的:

int hash = key.hashCode();

int index = (hash & 0x7FFFFFFF) % tab.length; 

而HashMap重新计算hash值,而且用与代替求模:

int hash = hash(k); 



int i = indexFor(hash, table.length);





static int hash(Object x) {  



 int h = x.hashCode();

 h += ~(h << 9);   

  h ^= (h >>> 14);   

  h += (h << 4);   

  h ^= (h >>> 10);   



  return h; 



} 



static int indexFor(int h, int length) {   

    return h & (length-1); 

} 

以上只是一些比较突出的区别,当然他们的实现上还是有很多不同的,比如 HashMap对null的操作。

 

你可能感兴趣的:(Hashtable)