zoukankan      html  css  js  c++  java
  • HashMap与Hashtable

    HashMap与Hashtable数据结构几乎是相同的(数组+链表),核心方法的实现也大致相同

    主要讨论不同,比较两者不同从JDK源码入手

    一、父类不同

    HashMap父类AbstractMap

    Hashtable父类Dictionary

      Dictionary类源码已注释被弃用

      Hashtable类源码注释也表明Hashtable已被淘汰

     * Java Collections Framework</a>.  Unlike the new collection
     * implementations, {@code Hashtable} is synchronized.  If a
     * thread-safe implementation is not needed, it is recommended to use
     * {@link HashMap} in place of {@code Hashtable}.  If a thread-safe
     * highly-concurrent implementation is desired, then it is recommended
     * to use {@link java.util.concurrent.ConcurrentHashMap} in place of
     * {@code Hashtable}.
    // 如果你不需要线程安全,那么使用HashMap,如果需要线程安全,那么使用ConcurrentHashMap。HashTable已经被淘汰了,不要在新的代码中再使用它。

    二、Synchronize

    Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。

    HashMap不是线程安全的,在多线程并发的环境下,使用HashMap时就必须要自己增加同步处理。

    (虽然HashMap不是线程安全的,但是它的效率会比Hashtable要好很多。这样设计是合理的。在我们的日常使用当中,大部分时间是单线程操作的。HashMap把这部分操作解放出来了。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。)

    三、初始容量和扩充容量

    HashMap初始容量16,扩容默认为原来容量的2倍

    Hashtable初始容量11,扩容默认为原来容量的2倍+1

    四、hash值算法不同

    HashMap:  具体原因可参考JDK源码学习笔记——HashMap

      1.int hash = (h = key.hashCode()) ^ (h >>> 16) ;

      2.int index = (table.length - 1) & hash;

      3.tableSizeFor()方法保证数组容量一定是2的次幂

    Hashtable:

      1.int hash = key.hashCode();
      2.int index = (hash & 0x7FFFFFFF) % tab.length;

    五、put时的不同

    1、HashMap支持key==null value==null,hash方法专门有对key==null的处理

        static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        }

    Hashtable不支持null

        public synchronized V put(K key, V value) {
            // Make sure the value is not null
            if (value == null) {// value==null抛异常
                throw new NullPointerException();
            }
    
            // Makes sure the key is not already in the hashtable.
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();// key==null抛异常
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> entry = (Entry<K,V>)tab[index];
            for(; entry != null ; entry = entry.next) {
                if ((entry.hash == hash) && entry.key.equals(key)) {
                    V old = entry.value;
                    entry.value = value;
                    return old;
                }
            }
    
            addEntry(hash, key, value, index);
            return null;
        }

    2、JDK1.8 HashMap引入了红黑树,链表超过最大长度(8),将链表改为红黑树再添加元素

    3、hash碰撞之后的处理

      HashMap:在链表尾加入元素

      Hashtable:在链表头加入元素

    
    
    

    参考资料:

    HashMap 和 HashTable 到底哪不同 ?

    HashMap 与HashTable的区别  

  • 相关阅读:
    MySQL没有备份情况下误删除表恢复
    CentOS 6下安装MySQL5.6
    关于mysql占用内存不释放的实验结论
    几种相似性度量(Similarity Measurement)
    几种平均数(Mean function)
    Ansible 多机文件分发、执行脚本并单机合并实验结果(Check point, 多线程异步执行,主机状态检测等)
    nginx-1.11.10 hello world module
    nginx-1.11.10 download, install, start and stop
    U-disk format
    test for cvx library in matlab
  • 原文地址:https://www.cnblogs.com/hexinwei1/p/9724213.html
Copyright © 2011-2022 走看看