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

    首先看两个类

    public class HashMap
        extends AbstractMap
        implements Map, Cloneable, Serializable
    public class Hashtable
        extends Dictionary
        implements Map, Cloneable, java.io.Serializable

         Dictionary 类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类。每个键和每个值都是一个对象。在任何一个 Dictionary 对象中,每个键至多与一个值相关联。给定一个 Dictionary 和一个键,就可以查找所关联的元素。任何非 null 对象都可以用作键或值。

    通常,应该在此类的实现中使用 equals 方法,以决定两个键是否相同。

        1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样。

        2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)。

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

        4.HashTable使用Enumeration,(继承与Dictionary ,获取到值得枚举)HashMap使用Iterator。

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

       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);
       }

    7. HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。

    8.HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 

    9. 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap)。 

    HashTable的实现如下

     1   public synchronized V put(K key, V value) {  //###### 注意这里1
     2     // Make sure the value is not null
     3     if (value == null) { //###### 注意这里 2
     4       throw new NullPointerException();
     5     }
     6     // Makes sure the key is not already in the hashtable.
     7     Entry tab[] = table;
     8     int hash = key.hashCode(); //###### 注意这里 3
     9     int index = (hash & 0x7FFFFFFF) % tab.length;//####注意4
    10     for (Entry e = tab[index]; e != null; e = e.next) {
    11       if ((e.hash == hash) && e.key.equals(key)) {
    12         V old = e.value;
    13         e.value = value;
    14         return old;
    15       }
    16     }
    17     modCount++;
    18     if (count >= threshold) {
    19       // Rehash the table if the threshold is exceeded
    20       rehash();
    21       tab = table;
    22       index = (hash & 0x7FFFFFFF) % tab.length;
    23     }
    24     // Creates the new entry.
    25     Entry e = tab[index];
    26     tab[index] = new Entry(hash, key, value, e);
    27     count++;
    28     return null;
    29   }

    注意1 方法是同步的,加了synchronized关键字
    注意2 方法不允许value==null
    注意3 方法调用了key的hashCode方法,如果key==null,会抛出空指针异常 HashMap的put方法如下

    注意3 HashTable直接使用对象的hashCode

    HashMap的实现如下

     1   public V put(K key, V value) { //###### 注意这里 1
     2     if (key == null)  //###### 注意这里 2
     3       return putForNullKey(value);
     4     int hash = hash(key.hashCode());
     5     int i = indexFor(hash, table.length);
     6     for (Entry e = table[i]; e != null; e = e.next) {
     7       Object k;
     8       if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
     9         V oldValue = e.value;
    10         e.value = value;
    11         e.recordAccess(this);
    12         return oldValue;
    13       }
    14     }
    15     modCount++;
    16     addEntry(hash, key, value, i);  //###### 注意这里 
    17     return null;
    18   }

    注意1 方法是非同步的
    注意2 方法允许key==null
    注意3 方法并没有对value进行任何调用,所以允许为null

  • 相关阅读:
    JAVA面试必备笔记:必须掌握的核心技能点
    这里有份最全的微服务,看完你就通关了
    大厂流出:JAVA面试必问面试题及答案
    阿里面试官:请叙述一下HTTP和HTTPS的区别
    [LeetCode] Serialize and Deserialize BST
    [LeetCode] Serialize and Deserialize Binary Tree
    [LeetCode] Next Greater Element II
    [LeetCode] Next Greater Element I
    [MySQL] ACID
    [Linux] linux下生成静态库和动态库
  • 原文地址:https://www.cnblogs.com/yixianyixian/p/3798713.html
Copyright © 2011-2022 走看看