java hashmap源码学习二 put&get

hashmap里面两个最重要的方法就是getput
一、put(Object key)方法的实现

public V put(K key, V value){
    //调用putval
    return putval(hash(key), key, value, false, true);
}

putval()的基本思路:
1.要是table为空,则创建新的table
2.要是table[(length-1)&hash(key)]为空,则创建新节点,否则(即原来有节点):
(1)如果key的hash值和这个节点的hash值相同,且key相同,则把这个节点的value改为新的值,key不变;
(2)如果该链为树,调用putTreeVal(),基本思想也应该是遍历,遇到相同的就改变value, 要是没相同key的节点就在树后加新节点
(3)其他情况,也就是链为单链,然后table上的那个节点key不一样,就遍历单链,遇到相同的就改变value,没有遇到就在链尾加新节点

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {
    Node<K, V>[] tab; Node<K, V> p; 
    int n; //长度
    int i; //索引
    if((tab = table) == null || (n == tab.length) == 0)
        n = (tab = resize()).length;
    if((p = tab[i = (n-1) & hash]) == null)
        tab[i] = newNode(hash, key, value, null);
    else{
        Node<K, V> e; //指向要改变的节点
        K k; //被放入元素的key值
        if(hash == p.hash && ((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        else if(p instanceof TreeNode)
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else{
            for(int binCount = 0; ;++binCount){ //遍历
                if((e = p.next) == null){
                    p.next = newNode(hash, key, value, null);
                    if(binCount >= TREEIFY_THRESHOLD - 1)
                        treeifyBin(tab, hash);
                    break;
                }
                if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                p = e;
            }
        }
        if (e != null) { 
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            afterNodeAccess(e);
            return oldValue;
        }
    }
    ++modCount;
    if (++size > threshold)
        resize();
    afterNodeInsertion(evict);
    return null;
}

二、get(Object key)和containsKey(Object key)的实现

public V get(Object key){
    Node<K, V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

public boolean containsKey(Object key){
    return getNode(hash(key), key) != null;
}

getNode()的基本思路:
(1)首先要保证table不为空,长度不为0并且table[(n-1)&hash]不为空,否则返回null
(2)首先检查第一个节点即table上的节点,如果hash值和key值都相等,就返回这个节点的value
(3)如果首节点不是要找的点,就往后遍历直到找到hash值和key值都和要找的点相同的节点,如果后面是树,则调用找查树的方法。

final Node<K, V> getNode(int hash, Object key){
    Node<K, V>[] tab; Node<K, V> first, e; int n; K k;
    if((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n-1) & hash]) != null){
        if(first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if((e = first.next) != null){
            if(first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do{
                if(e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            }while((e = e.next) != null);
        }
    }
    return null;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值