复习HashMap源码增删改查

HashMap
⭐对key的hash运算
    static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        }
  通过对key的异或运算 ^ ,将高位与低位进行互换,从而减低了hash冲突,进而降低了系统损耗。
⭐public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
    1.首先判断HashMap是否经过初始化,如果没有经过初始化,默认槽点的数量为16,阀值为负载因子0.75*默认槽点的数量为12.这是判断是否需要扩容的依据。
    2.根据(n - 1) & hash算法(ps:其实就是 hash mod size结果为槽点位置),找到槽点的位置,然后判断槽点上是否有值:
        2.1如果没有,则直接将Node节点放到槽点上即可。
        2.2如果有,则判断if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
    解释:(旧的Node的节点.hash与插入Node的节点.hash是否相等 && ((旧的Node的节点.key与插入Node的节点.key的地址是否相等) || (插入Node的节点.key不为NULL &&  插入Node的节点.key与旧的Node的节点.key的值是否相等))
)
            2.2.1如果找到则退出循环,将旧Node节点的值进行替换;
            2.2.2如果找不到,则尾插法,插入到链表的尾部,并且判断链表长度是否>=8,如果大于,则将链表转变成红黑树,便于查找使用(ps:以链表举例,JDK1.8尾插法,JDK1.7头插法)

⭐public V remove(Object key)
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (p = tab[index = (n - 1) & hash]) != null) {****}
        1.先判断该HashMap槽点链是否为NULL,是否有元素,并找到要删除的槽点判断该槽点上是否有元素
            1.1有,则继续执行;
                1.1.1判断槽点上的元素是否正是要删除的元素;
                    1.1.1.1如果是,则 tab[index] = node.next;
                    1.1.1.2如果不是,则进行从头到尾进行遍历,(ps:以链表为例)
                         do {
                            if (e.hash == hash &&
                                ((k = e.key) == key ||
                                 (key != null && key.equals(k)))) {
                                node = e;
                                break;
                            }
                            p = e;
                        } while ((e = e.next) != null);
                    找到后,则  p.next = node.next;
            1.2没有,则return null;
⭐public V get(Object key)
        if ((tab = table) != null && (n = tab.length) > 0 &&(first = tab[(n - 1) & hash]) != null)
        1.🎇先判断该HashMap的槽点链不为NULL,并且有元素,并且通过hash计算key找到该槽点,槽点上是有值的
             if (first.hash == hash && // always check first node
                        ((k = first.key) == key || (key != null && key.equals(k))))
                        return first;
            1.1❀判断要找的key是否为该槽点的首元素,如果是则返回该Node节点
              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);
                }
            1.2❀如果不是则对该槽点上的链表进行从头到尾遍历(ps:以链表举例,链表数量大于8,则该槽点上的数据结构为红黑树)
            

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值