共同学习Java源代码-数据结构-HashMap(九)

来源:互联网 发布:python注释快捷键 编辑:程序博客网 时间:2024/06/09 22:52
    public V remove(Object key) {
        Node<K,V> e;
        return (e = removeNode(hash(key), key, null, false, true)) == null ?
            null : e.value;

    }

这个是很常用的删除键的方法 首先创建节点对象e 然后调用removeNode方法将参数键的哈希值,键,为空的参数值传过去,代表不考虑参数值是否匹配的false,代表删除时可以移动其他节点的true

将removeNode方法返回值赋给e 判断e是否为空 为空就返回null 否则返回e的值


   final Node<K,V> removeNode(int hash, Object key, Object value,
                               boolean matchValue, boolean movable) {
        Node<K,V>[] tab; Node<K,V> p; int n, index;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (p = tab[index = (n - 1) & hash]) != null) {
            Node<K,V> node = null, e; K k; V v;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                node = p;
            else if ((e = p.next) != null) {
                if (p instanceof TreeNode)
                    node = ((TreeNode<K,V>)p).getTreeNode(hash, key);
                else {
                    do {
                        if (e.hash == hash &&
                            ((k = e.key) == key ||
                             (key != null && key.equals(k)))) {
                            node = e;
                            break;
                        }
                        p = e;
                    } while ((e = e.next) != null);
                }
            }
            if (node != null && (!matchValue || (v = node.value) == value ||
                                 (value != null && value.equals(v)))) {
                if (node instanceof TreeNode)
                    ((TreeNode<K,V>)node).removeTreeNode(this, tab, movable);
                else if (node == p)
                    tab[index] = node.next;
                else
                    p.next = node.next;
                ++modCount;
                --size;
                afterNodeRemoval(node);
                return node;
            }
        }
        return null;
    }

这个就是removeNode方法 我说简略一些哈 毕竟很多代码都重复了

首先判断哈希桶数组是否为空 哈希桶数组的长度是否大于0 以及参数哈希值所在的那个桶的首元素是否不为空 如果不满足条件就没有然后了

先判断桶的首节点的键是否和参数的键一致或为同一对象 如果确实是要删除首节点 那么就固化这个节点 让临时变量引用这个节点

如果要删除的不是首节点 且首节点有下一个节点 再判断桶的结构是否为树 如果为树 就调用树的方法获取并固化节点 如果桶结构是链表 就遍历链表 获取节点并固化

判断如果节点不为空 且要么matchValue为false 要么传入的值和节点的值一样或为同一对象 就进行删除 

判断固化的节点是否是树节点 如果是树节点就调用树的方法删除节点 

如果是链表并且node和p是相等的 也就是要删除的是第一个元素 那么就将桶的对应下标引用这个链表第二个元素 如果node和p不一致(do while遍历的时候 p在链表中比node要靠前)就将p的下一个节点直接引用node的下一个节点 node为空引用 

然后对modCount自增 代表修改次数自增 然后size自减 代表键值对少了一个  最后返回node对象 afterNodeRemoval是空实现


    public void clear() {
        Node<K,V>[] tab;
        modCount++;
        if ((tab = table) != null && size > 0) {
            size = 0;
            for (int i = 0; i < tab.length; ++i)
                tab[i] = null;
        }
    }

这个是清空所有键值对的方法 不细说了 修改次数自增 然后所有桶元素全部为空


    public boolean containsValue(Object value) {
        Node<K,V>[] tab; V v;
        if ((tab = table) != null && size > 0) {
            for (int i = 0; i < tab.length; ++i) {
                for (Node<K,V> e = tab[i]; e != null; e = e.next) {
                    if ((v = e.value) == value ||
                        (value != null && value.equals(v)))
                        return true;
                }
            }
        }
        return false;
    }

这个方法是判断是否包含某个值的方法 也不细说了 就是挨个遍历桶 然后挨个遍历链表或树 多说一句 树也有next节点 这也是为了方便遍历 找到值了 就返回true 否则返回false

阅读全文
0 0