• HashMap.put()和get()原理


    /** 
     * Returns the value to which the specified key is mapped, 
     * or if this map contains no mapping for the key. 
     * 
     * 获取key对应的value 
     */  
    public V get(Object key) {  
        if (key == null)  
            return getForNullKey();  
        //获取key的hash值  
        int hash = hash(key.hashCode());  
        // 在“该hash值对应的链表”上查找“键值等于key”的元素  
        for (Entry<K,V> e = table[indexFor(hash, table.length)];  
             e != null;  
             e = e.next) {  
            Object k;  
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  
                return e.value;  
        }  
        return null;  
    }  
    
    /** 
     * Offloaded version of get() to look up null keys.  Null keys map 
     * to index 0.   
     * 获取key为null的键值对,HashMap将此键值对存储到table[0]的位置 
     */  
    private V getForNullKey() {  
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {  
            if (e.key == null)  
                return e.value;  
        }  
        return null;  
    }  
    
    /** 
     * Returns <tt>true</tt> if this map contains a mapping for the 
     * specified key. 
     * 
     * HashMap是否包含key 
     */  
    public boolean containsKey(Object key) {  
        return getEntry(key) != null;  
    }  
    
    /** 
     * Returns the entry associated with the specified key in the 
     * HashMap.   
     * 返回键为key的键值对 
     */  
    final Entry<K,V> getEntry(Object key) {  
        //先获取哈希值。如果key为null,hash = 0;这是因为key为null的键值对存储在table[0]的位置。  
        int hash = (key == null) ? 0 : hash(key.hashCode());  
        //在该哈希值对应的链表上查找键值与key相等的元素。  
        for (Entry<K,V> e = table[indexFor(hash, table.length)];  
             e != null;  
             e = e.next) {  
            Object k;  
            if (e.hash == hash &&  
                ((k = e.key) == key || (key != null && key.equals(k))))  
                return e;  
        }  
        return null;  
    }  
    
    
    /** 
     * Associates the specified value with the specified key in this map. 
     * If the map previously contained a mapping for the key, the old 
     * value is replaced. 
     * 
     * 将“key-value”添加到HashMap中,如果hashMap中包含了key,那么原来的值将会被新值取代 
     */  
    public V put(K key, V value) {  
        //如果key是null,那么调用putForNullKey(),将该键值对添加到table[0]中  
        if (key == null)  
            return putForNullKey(value);  
        //如果key不为null,则计算key的哈希值,然后将其添加到哈希值对应的链表中  
        int hash = hash(key.hashCode());  
        int i = indexFor(hash, table.length);  
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {  
            Object k;  
            //如果这个key对应的键值对已经存在,就用新的value代替老的value。  
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
                V oldValue = e.value;  
                e.value = value;  
                e.recordAccess(this);  
                return oldValue;  
            }  
        }  
    
        modCount++;  
        addEntry(hash, key, value, i);  
        return null;  
    }

    get:通过获取key的hashcode,然后调用 hash() 获得hash值,然后在“该hash值对应的链表”上查找“键值等于key”的元素。

    put:通过获取key的hashcode,然后调用 hash() 获得hash值,然后将其添加到哈希值对应的链表中(如果key为null,则将该键值对存储到table[0]中),如果这个key对应的键值对已经存在,就用新的value代替老的value。

  • 相关阅读:
    Centos 6.5 在 Dell 服务器安装的记录
    【转载】你真的了解补码吗
    【转载】我对补码的理解
    记录一下家里双路由实现wifi漫游功能
    中国大学MOOC | C语言程序设计入门 第8周编程练习 翁恺
    华为卡刷包线刷方法
    串口通信
    端口复用和端口重映射
    软件仿真和硬件仿真
    FPGA之四位LED灯
  • 原文地址:https://www.cnblogs.com/liuqing576598117/p/10250043.html
Copyright © 2020-2023  润新知