• HashMap与HashTable的区别


    链接:https://www.nowcoder.com/questionTerminal/687a87f9018e4ba4a747ff31ffbcd9c9?toCommentId=1771794
    来源:牛客网

    看看继承体系
    然后HashMap可以允许Null做键或者值,但是Null的键 只能有一个

    这个表上的知识能够让你明白个体系,但是具体我们看看HashMap的码源吧
    1.都实现了map接口
    public class HashMap<K,V>
        extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable, Serializable
    public class Hashtable<K,V>
        extends Dictionary<K,V>
        implements Map<K,V>, Cloneable, java.io.Serializable
    2.Hashtable的主要方法都是同步方法
     public synchronized V put(K key, V value) 
     public synchronized V get(Object key)
    所以Hashtable是线程安全的
    HashMap的主要方法
    public V put(K key, V value)
    public V get(Object key)
    3.是否允许控制这个问题看看码源
    Hashtable中不允许空值存在
     if (value == null) {
                throw new NullPointerException();
       }
    然而HashMap通过码源检查发现
     if (key == null)
                return putForNullKey(value);
    允许null作为键或者值
    由于key-value形式,所以只能有一个Null的key
    4.关于hash值的问题
    HashMap将hash值重新计算是一个
     final int hash(Object k) {
            int h = hashSeed;
            if (0 != h && k instanceof String) {
                return sun.misc.Hashing.stringHash32((String) k);
            }

            h ^= k.hashCode();

            // This function ensures that hashCodes that differ only by
            // constant multiples at each bit position have a bounded
            // number of collisions (approximately 8 at default load factor).
            h ^= (h >>> 20) ^ (h >>> 12);
            return h ^ (h >>> 7) ^ (h >>> 4);
        }
    这样的方法,进行哈希运算,新的hash值
    而Hashtable采取的是
     int hash = key.hashCode();的方式进行计算
    5.关于扩容问题HashMap采取直接扩大两倍,初始长度16
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
     public HashMap(Map<? extends K, ? extends V> m) {
            this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
                          DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
            inflateTable(threshold);

            putAllForCreate(m);
        }

     if ((size >= threshold) && (null != table[bucketIndex])) {
                resize(2 * table.length);
                hash = (null != key) ? hash(key) : 0;
                bucketIndex = indexFor(hash, table.length);
            }
    而HashTable的策略是乘以2增长,初始11
    public Hashtable(Map<? extends K, ? extends V> t) {
            this(Math.max(2*t.size(), 11), 0.75f);
            putAll(t);
        }

     
  • 相关阅读:
    最大子段和之可交换
    最大子段和之M子段和
    前端开发-日常开发沉淀之生产环境与开发环境
    开发技巧-解决打开谷歌浏览器跳转问题
    前端调试-跨域解决方式
    postman自动化,测试脚本
    自动化脚本测试,postman使用沉淀
    HMAC-SHA256 签名方法各个语音的实现方式之前端JavaScriptes6
    React中redux表单编辑
    前端JavaScript获取时间戳
  • 原文地址:https://www.cnblogs.com/ad-zhou/p/9809992.html
Copyright © 2020-2023  润新知