java8 HashMap数据结构实现源码解析

本文详细解析了Java8 HashMap中的红黑树数据结构,包括Node基础元素、TreeNode类定义、插入查找实现、形态转换以及扩容切分,深入探讨了红黑树在HashMap中的应用。
摘要由CSDN通过智能技术生成

目录

一、基础元素Node

二、红黑树元素TreeNode

1、类定义和类属性

2、基础方法:

 3、红黑树插入元素实现

 4、红黑树的查找实现

5、红黑树的形态转换实现

6、红黑树的扩容切分实现


一、基础元素Node

static class Node<K,V> implements Map.Entry<K,V> {
        //key的hash值
        final int hash;
        final K key;
        V value;
        //通过next属性将多个hash值相同的元素关联起来,形成单向链表
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }

       实现很简单,关键是next属性,插入、查找、删除用法如下:

    @Test
    public void test8() throws Exception {
        Node<String,Integer> first=new Node<>(1, "1", 1, null);
        Node<String,Integer> node2=new Node<>(1, "2", 1, null);
        Node<String,Integer> node3=new Node<>(1, "3", 1, null);
        Node<String,Integer> node4=new Node<>(1, "4", 1, null);
        Node<String,Integer> node5=new Node<>(1, "5", 1, null);
        //插入时建立链式关系
        first.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        //从头元素开始遍历查找
        Node<String,Integer> n=first;
        do{
            if(n.key.equals("5")){
                System.out.println("====元素查找======");
                System.out.println(n);
            }
        }while ((n=n.next)!=null);
        //移除元素node2
        first.next=node3;
        node2.next=null;
        System.out.println("====移除元素======");
        n=first;
        do{
            System.out.println(n);
        }while ((n=n.next)!=null);
    }

二、红黑树元素TreeNode

1、类定义和类属性

      TreeNode继承自LinkedHashMap.Entry<K,V>,后者继承自HashMap.Node<K,V>,只是增加了两个属性before和after,用于保存当前节点的前后节点引用,从而形成一条可以双向遍历的链表。TreeNode继承自LinkedHashMap.Entry<K,V>是为了方便LinkedHashMap实现,本身并没有直接使用before和after两个属性。LinkedHashMap.Entry<K,V>的定义如下图:

      TreeNode定义的属性如下图:

       注意TreeNode的实现同时维护了红黑树和双向链式两种应用关系,这样便于在红黑树和链表之间做形态转换。  

2、基础方法:

        /**
         * 返回当前节点的根节点
         */
        final TreeNode<K,V> root() {
            for (TreeNode<K,V> r = this, p;;) {
                //该节点的父节点为null时该节点为根节点
                if ((p = r.parent) == null)
                    return r;
                r = p;
            }
        }

         
        /**
         * 递归检查当前节点是否符合双向链表以及红黑树规则
         * 该方法在红黑树发生改变时都会执行一次,确保改变后红黑树符合规范
         */
        static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
            TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
                tb = t.prev, tn = (TreeNode<K,V>)t.next;
            //是否符合双向链表规则
            if (tb != null && tb.next != t)
                return false;
            if (tn != null && tn.prev != t)
                return false;
            //是否符合红黑树规则
            if (tp != null && t != tp.left && t != tp.right)
                return false;
            //左节点的hash值必须小于根节点hash值
            if (tl != null && (tl.parent != t || tl.hash > t.hash))
                return false;
            //右节点hash值大于根节点hash值
            if (tr != null && (tr.parent != t || tr.hash < t.hash))
                return false;
            //红色节点的子节点一定不能是红色
            if (t.red && tl != null && tl.red && tr != null && tr.red)
                return false;
            //递归检查左节点和右节点
            if (tl != null && !checkInvariants(tl))
                return false;
            if (tr != null && !checkInvariants(tr))
                return false;
            return true;
        }

        
        /**
 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值