zoukankan      html  css  js  c++  java
  • 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的操作。

  • 相关阅读:
    一种在【微服务体系】下的【参数配置神器】
    阅读源代码之“那是我的青春”
    我谈防御式编程
    博客开篇
    redis-sentinel-cluster-codis
    redis-复制
    redis-持久化
    redis-事件
    圆角矩形精度条
    小程序---canvas画图,生成分享图片,画图文字换行
  • 原文地址:https://www.cnblogs.com/likai198981/p/2851353.html
Copyright © 2011-2022 走看看