zoukankan      html  css  js  c++  java
  • HashTable和HashMap的区别

    继承的父类不同:

     * @since JDK1.0
     */
    public class Hashtable<K,V>
        extends Dictionary<K,V>
        implements Map<K,V>, Cloneable, java.io.Serializable {
     * @since   1.2
     */
    
    public class HashMap<K,V>
        extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable, Serializable
    {

    初始数组长度不同:

        /**
         * Constructs a new, empty hashtable with a default initial capacity (11)
         * and load factor (0.75).
         */
        public Hashtable() {
        this(11, 0.75f);
        }
       /**
         * Constructs an empty <tt>HashMap</tt> with the default initial capacity
         * (16) and the default load factor (0.75).
         */
        public HashMap() {
            this.loadFactor = DEFAULT_LOAD_FACTOR;
            threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
            table = new Entry[DEFAULT_INITIAL_CAPACITY];
            init();
        }

    方法时否是同步的:
    key是否可以是null:HashMap可以,HashTable不可以
    value是不可以是null,HashMap可以,HashTable不可以

    
    
       /**
         * Maps the specified <code>key</code> to the specified
         * <code>value</code> in this hashtable. Neither the key nor the
         * value can be <code>null</code>. <p>
         *
         * The value can be retrieved by calling the <code>get</code> method
         * with a key that is equal to the original key.
         *
         * @param      key     the hashtable key
         * @param      value   the value
         * @return     the previous value of the specified key in this hashtable,
         *             or <code>null</code> if it did not have one
         * @exception  NullPointerException  if the key or value is
         *               <code>null</code>
         * @see     Object#equals(Object)
         * @see     #get(Object)
         */
        public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }
    
        // Makes sure the key is not already in the hashtable.
        Entry tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
            V old = e.value;
            e.value = value;
            return old;
            }
        }
    
        modCount++;
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();
    
                tab = table;
                index = (hash & 0x7FFFFFFF) % tab.length;
        }
    
        // Creates the new entry.
        Entry<K,V> e = tab[index];
        tab[index] = new Entry<K,V>(hash, key, value, e);
        count++;
        return null;
        }
     HashMap:
     /**
         * Associates the specified value with the specified key in this map.
         * If the map previously contained a mapping for the key, the old
         * value is replaced.
         *
         * @param key key with which the specified value is to be associated
         * @param value value to be associated with the specified key
         * @return the previous value associated with <tt>key</tt>, or
         *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
         *         (A <tt>null</tt> return can also indicate that the map
         *         previously associated <tt>null</tt> with <tt>key</tt>.)
         */
        public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
            }
    
            modCount++;
            addEntry(hash, key, value, i);
            return null;
        }
    HashTable:
    如果value是null,则会抛NullPointerException
    
        /**
         * Returns a string representation of this <tt>Hashtable</tt> object
         * in the form of a set of entries, enclosed in braces and separated
         * by the ASCII characters "<tt>,&nbsp;</tt>" (comma and space). Each
         * entry is rendered as the key, an equals sign <tt>=</tt>, and the
         * associated element, where the <tt>toString</tt> method is used to
         * convert the key and element to strings.
         *
         * @return  a string representation of this hashtable
         */
        public synchronized String toString() {
        int max = size() - 1;
        if (max == -1)
            return "{}";
    
        StringBuilder sb = new StringBuilder();
        Iterator<Map.Entry<K,V>> it = entrySet().iterator();
    
        sb.append('{');
        for (int i = 0; ; i++) {
            Map.Entry<K,V> e = it.next();
                K key = e.getKey();
                V value = e.getValue();
                sb.append(key   == this ? "(this Map)" : key.toString());
            sb.append('=');
            sb.append(value == this ? "(this Map)" : value.toString());
    
            if (i == max)
            return sb.append('}').toString();
            sb.append(", ");
        }
        }



    put和get时计算hash值的算法不同:
    HashTable直接使用了hashCode()方法的值;

    HashMap:
      
      public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
    HashMap:
        /**
         * Applies a supplemental hash function to a given hashCode, which
         * defends against poor quality hash functions.  This is critical
         * because HashMap uses power-of-two length hash tables, that
         * otherwise encounter collisions for hashCodes that do not differ
         * in lower bits. Note: Null keys always map to hash 0, thus index 0.
         */
        static int hash(int h) {
            // This function ensures that hashCodes that differ only by
            // constant multiples at each bit position have a bounded
            // number of collisions (approximately 8 at default load factor).
            h ^= (h >>> 20) ^ (h >>> 12);
            return h ^ (h >>> 7) ^ (h >>> 4);
        }
    HashTable:
    
        public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }
    
        // Makes sure the key is not already in the hashtable.
        Entry tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;

    扩容的大小不同:

    HashTable 
    
     /**
         * Increases the capacity of and internally reorganizes this
         * hashtable, in order to accommodate and access its entries more
         * efficiently.  This method is called automatically when the
         * number of keys in the hashtable exceeds this hashtable's capacity
         * and load factor.
         */
        protected void rehash() {
        int oldCapacity = table.length;
        Entry[] oldMap = table;
    
        int newCapacity = oldCapacity * 2 + 1;
        Entry[] newMap = new Entry[newCapacity];
    
        modCount++;
        threshold = (int)(newCapacity * loadFactor);
        table = newMap;
    
        for (int i = oldCapacity ; i-- > 0 ;) {
            for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
            Entry<K,V> e = old;
            old = old.next;
    
            int index = (e.hash & 0x7FFFFFFF) % newCapacity;
            e.next = newMap[index];
            newMap[index] = e;
            }
        }
        }
    HashMap
        /**
         * Adds a new entry with the specified key, value and hash code to
         * the specified bucket.  It is the responsibility of this
         * method to resize the table if appropriate.
         *
         * Subclass overrides this to alter the behavior of put method.
         */
        void addEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
            table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
            if (size++ >= threshold)
                resize(2 * table.length);
        }

    http://my.oschina.net/placeholder/blog/180069

    http://blog.csdn.net/chenssy/article/details/22896871 

  • 相关阅读:
    【并行计算-CUDA开发】CUDA shared memory bank 冲突
    【并行计算-CUDA开发】CUDA shared memory bank 冲突
    【并行计算-CUDA开发】CUDA bank conflict in shared memory
    【并行计算-CUDA开发】CUDA bank conflict in shared memory
    【并行计算-CUDA开发】从熟悉到精通 英伟达显卡选购指南
    【并行计算-CUDA开发】从熟悉到精通 英伟达显卡选购指南
    【C/C++开发】【VS开发】win32位与x64位下各类型长度对比
    【C/C++开发】【VS开发】win32位与x64位下各类型长度对比
    【并行计算-CUDA开发】浅谈GPU并行计算新趋势
    【并行计算-CUDA开发】浅谈GPU并行计算新趋势
  • 原文地址:https://www.cnblogs.com/softidea/p/5487973.html
Copyright © 2011-2022 走看看