一步一步解析java集合框架HashMap源码(3)

来源:互联网 发布:linux下如何删除用户 编辑:程序博客网 时间:2024/05/01 19:46

通过键获取对应值

    public static void main(String[] args) {        Map<String,String> map=new HashMap<String,String>();        map.put("firstKey","firstValue");        map.put("secondKey","secondValue");        map.put("fir","thirdValue");        map.put("first","fourthValue");        System.out.println("firstKey:"+map.get("firstKey"));    }

输出结果:

firstKey:firstValue

源码分析:

    /**     * 通过键获取值     */    public V get(Object key) {        Node<K,V> e;        return (e = getNode(hash(key), key)) == null ? null : e.value;    }    /**     * 获取键对应节点     * @param hash hash for key     * @param key 键     * @return the node, or null if none     */    final Node<K,V> getNode(int hash, Object key) {        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;        //(n - 1) & hash直接定位索引,再散列之后依然可以定位        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;    }

删除节点

    public static void main(String[] args) {        Map<String,String> map=new HashMap<String,String>();        map.put("firstKey","firstValue");        map.put("secondKey","secondValue");        map.put("fir","thirdValue");        map.put("first","fourthValue");        map.remove("firstKey");        System.out.println("firstKey:"+map.get("firstKey"));    }

运行:

firstKey:null

源码分析:

    /**     * 返回删除节点值     * 不存在返回null     */    public V remove(Object key) {        Node<K,V> e;        return (e = removeNode(hash(key), key, null, false, true)) == null ?            null : e.value;    }    /**     *返回删除的节点     *     * @param hash hash for key     * @param key 键     * @param value 值     * @param matchValue if true only remove if value is equal     * @param movable if false do not move other nodes while removing     * @return the node, or null if none     */    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;    }
0 0