zoukankan      html  css  js  c++  java
  • HashMap与HashTable联系与区别

    HashMapHashTable

    1.hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
    2.hashTable同步的,而HashMap是非同步的,效率上比hashTable要高,HashMap不是线程安全的 ,HashTable是线程安全的一个Collection。
    3.hashMap允许空键值,而hashTable不允许。

    ashtable继承自Dictionary类,而HashMap是Map接口的一个实现。这里要说明一下Dictionary类是jdk1.0中就有的,而Map接口是1.2之后才有的,当然与此同时Hashtable也实现了Map接口。

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

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

    }

     

    HashMap和Hashtable的相同点

    HashMapHashtable都是存储“键值对(key-value)”的散列表,而且都是采用拉链法实现的。
    存储的思想都是:通过table数组存储,数组的每一个元素都是一个Entry;而一个Entry就是一个单向链表Entry链表中的每一个节点就保存了key-value键值对数据

    添加key-value键值对:首先,根据key值计算出哈希值,再计算出数组索引(即,该key-value在table中的索引)。然后,根据数组索引找到Entry(即,单向链表),再遍历单向链表,将key和链表中的每一个节点的key进行对比。若key已经存在Entry链表中,则用该value值取代旧的value值;若key不存在Entry链表中,则新建一个key-value节点,并将该节点插入Entry链表的表头位置。
    删除key-value键值对:删除键值对,相比于“添加键值对”来说,简单很多。首先,还是根据key计算出哈希值,再计算出数组索引(即,该key-value在table中的索引)。然后,根据索引找出Entry(即,单向链表)。若节点key-value存在与链表Entry中,则删除链表中的节点即可。

    HashMap和Hashtable的不同点

    1 继承和实现方式不同

    HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。
    Hashtable 继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口。

    2 线程安全不同

    Hashtable的几乎所有函数都是同步的,即它是线程安全的,支持多线程。
    而HashMap的函数则是非同步的,它不是线程安全的。 若要在多线程中使用HashMap,需要我们额外的进行同步处理。 对HashMap的同步处理可以使用Collections类提供的synchronizedMap静态方法,或者直接使用JDK 5.0之后提供的java.util.concurrent包里的ConcurrentHashMap类。

    3 对null值的处理不同

    HashMap的key、value都可以为null
    Hashtable的key、value都不可以为null

    Hashtable的key或value,都不能为null!否则,会抛出异常NullPointerException。
    HashMap的key、value都可以为null。 当HashMap的key为null时,HashMap会将其固定的插入table[0]位置(即HashMap散列表的第一个位置);而且 table[0]处只会容纳一个key为null的值,当有多个key为null的值插入的时候,table[0]会保留最后插入的value。

    4 支持的遍历种类不同

    HashMap只支持Iterator(迭代器)遍历。
    而Hashtable支持Iterator(迭代器)和Enumeration(枚举器)两种方式遍历。

    5 通过Iterator迭代器遍历时,遍历的顺序不同

    HashMap是“从前向后”的遍历数组;再对数组具体某一项对应的链表,从表头开始进行遍历。
    Hashtable是“从后往前”的遍历数组;再对数组具体某一项对应的链表,从表头开始进行遍历。

    6 容量的初始值 和 增加方式都不一样

    HashMap默认的容量大小是16;增加容量时,每次将容量变为“原始容量x2”
    Hashtable默认的容量大小是11;增加容量时,每次将容量变为“原始容量x2 + 1”。

    7 添加key-value时的hash值算法不同

    HashMap添加元素时,是使用自定义的哈希算法。
    Hashtable没有自定义哈希算法,而直接采用的key的hashCode()。

     

    HashMap和WeakHashMap的相同点

    1 它们都是散列表,存储的是“键值对”映射。
    2 它们都继承于AbstractMap,并且实现Map基础。
    3 它们的构造函数都一样。
       它们都包括4个构造函数,而且函数的参数都一样。
    4 默认的容量大小是16,默认的加载因子是0.75。
    5 它们的“键”和“值”都允许为null。
    6 它们都是“非同步的”。

    HashMap和WeakHashMap的不同点

    1 HashMap实现了Cloneable和Serializable接口,而WeakHashMap没有。

    2 HashMap的“键”是“强引用(StrongReference)”,而WeakHashMap的键是“弱引用(WeakReference)”。

  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/wzyxidian/p/3783621.html
Copyright © 2011-2022 走看看