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

  • 相关阅读:
    linux常用命令---文件操作
    Django 框架中定时触发脚本
    jquery 中选择当前标签下众多相同子标签中的第n个
    Django + DRF + Elasticsearch 实现搜索功能
    django 使用celery 实现异步任务
    python 通过 pymysql模块 操作 mysql 数据库
    django 自定义中间件 middleware
    django 使用其自带的验证系统 进行用户名有效性验证 登录状态验证 登入操作 登出操作
    python脚本 读取excel格式文件 并进行处理的方法
    python 将json格式的数据写入csv格式的文件中
  • 原文地址:https://www.cnblogs.com/yixianyixian/p/3798713.html
Copyright © 2011-2022 走看看