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

    HashMap与HashTable的区别

    1:    hashtable是线程安全的:其实现方法中都添加了synchornized关键字来确保同步,但也造成了效率的降低;

      hashmap非线程安全,无特殊需求时应使用hashmap。多线程下,使用hashmap需使用Collections.synchronizedMap()获取一个线程安全的集合Map。

         Map map = Collections.synchronizedMap(new HashMap()); 

        (其原理为:Collections中定义一个实现Map接口的名为SynchronizedMap的内部类,Collections.synchronizedMap()方法帮我们在操作HashMap时自动添加了synchronized来实现线程同步,类似的其它Collections.synchronizedXX方法也是类似原理)

    2:  HashMap可以使用null作为key和value

      其哈希函数采用: return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); 

      通过hash获取的具体存放地址为: return h & (length-1); 

      ref:https://www.zhihu.com/question/20733617/answer/111577937

         由于h是32位的int类型,h右移16位后与自身进行异或,混合原始哈希码的高位和低位,以此来加大低位的随机性。对获取的hash值与当前长度减1进行与操作获取实际存储位置,若果key为null,则其h为0,最终返回的地址也是0,存储在数组下标为0的位置。

        计算出对象的存储地址后,若该地址处没有对象,则直接放入;若存在对象,则比较已存在对象的key是否与要存入对象的key相等,若相等则替换;若不等,则对象存入链表头位置,已存在对象向后移动。注意:HashMap中只能存放一个key为null的对象,value的则不限制。

      HashTable不允许使用null作为key;

      其哈希函数采用: int hash = key.hashCode(); 地址获取采用  int index = (hash & 0x7FFFFFFF) % tab.length; 

      相同点:都采用数组加链表的底层模式;

    transient Entry[] table;
     
    static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        final int hash;
        ……
    }

    3:  接口实现不同:

      HashMap是对Map接口的实现,HashTable实现了Map接口和Dictionary抽象类

    4:初始容量不同

      HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75
      HashMap扩容时是当前容量翻倍即:capacity*2,Hashtable扩容时是容量翻倍+1即:capacity*2+1

    话外:Hashtable与HashMap的remove,get,put,containskey等方法都是通过hash计算地址,效率较高;

       但是containsValue方法比较粗暴,直接便利所有元素找到value,没有前面方法的高效。

    5:补充:HashMap的初始容量为什么是 1<<4 ?

      参考:博客园-YSOcean-由HashMap哈希算法引出的求余%和与运算&转换问题

      初始容量设置为16,且每次容量扩增两倍,是为了满足hash算法:当 lenth = 2n 时,X % length = X & (length - 1);我们知道:求取存储位置的过程中,hashmap用与运算取代了模运算以提高效率,任意一个二进制数对 2k 取余时,我们可以将这个二进制数与(2k-1)进行按位与运算,保留的即使余数。

    6:jdk1.8以后对hashmap有所改进,对于table中长度超过8的链表,转化成红黑树实现。

  • 相关阅读:
    dutacm.club_1094_等差区间_(线段树)(RMQ算法)
    dutacm.club_1087_Common Substrings_(KMP)_(结合此题通俗理解kmp的next数组)
    dutacm.club_1089_A Water Problem_(dp)
    14年第五届蓝桥杯第八题_地宫取宝_(记忆化搜索)
    14年第五届蓝桥杯第七题_蚂蚁感冒_(思维)
    dutacm.club_1085_Water Problem_(矩阵快速幂)
    HDU_2476_String painter_(区间dp)
    第五届蓝桥杯校内选拔第七题_(树型dp)
    第五届蓝桥杯校内选拔第六题_(dfs)
    15年第六届蓝桥杯第九题_(矩阵快速幂优化的动态规划)
  • 原文地址:https://www.cnblogs.com/whtblog/p/8819186.html
Copyright © 2011-2022 走看看