ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

技术问答-17

2021-04-14 11:55:51  阅读:115  来源: 互联网

标签:TreeNode 17 问答 技术 hashCode && null root 节点


compareComparables:

identityHashCode : https://www.cnblogs.com/godtrue/p/6341473.html
https://blog.csdn.net/qsdnmd/article/details/82914460

 /**
     * Returns k.compareTo(x) if x matches kc (k's screened comparable
     * class), else 0.
         * 比较k 与 x  如果x为空 或者 x类不是kc(kc是上一步获取的继承Comparable的添加泛型的变量) 返回0 
         *  否则返回k.compareTo(x)
     */@SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparablestatic int compareComparables(Class<?> kc, Object k, Object x) {return (x == null || x.getClass() != kc ? 0 :((Comparable)k).compareTo(x));}

/**
 * 一个对象的hashCode和identityHashCode 的关系:
 * 1:对象的hashCode,一般是通过将该对象的内部地址转换成一个整数来实现的
 * 2:当一个类没有重写Object类的hashCode()方法时,它的hashCode和identityHashCode是一致的
 * 3:当一个类重写了Object类的hashCode()方法时,它的hashCode则有重写的实现逻辑决定,此时的hashCode值一般就不再和对象本身的内部地址有相应的哈希关系了
 * 4:当null调用hashCode方法时,会抛出空指针异常,但是调用System.identityHashCode(null)方法时能正常的返回0这个值
 * 5:一个对象的identityHashCode能够始终和该对象的内部地址有一个相对应的关系,从这个角度来讲,它可以用于代表对象的引用地址,所以,在理解==这个操作运算符的时候是比较有用的
 *
 */

	 /**
	  * 比较a和b 要么返回-1 要么返回1   反正就是不能相等
     */static int tieBreakOrder(Object a, Object b) {int d;if (a == null || b == null ||(d = a.getClass().getName(). compareTo(b.getClass().getName())) == 0)d = (System.identityHashCode(a) <= System.identityHashCode(b) ? -1 : 1);return d;}

/**
	 * 把红黑树的根节点设为  其所在的数组槽 的第一个元素
	 * 首先明确:TreeNode既是一个红黑树结构,也是一个双链表结构
	 * 这个方法里做的事情,就是保证树的根节点一定也要成为链表的首节点
	 */static <K,V> void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root) {int n;if (root != null && tab != null && (n = tab.length) > 0) { // 根节点不为空 并且 HashMap的元素数组不为空int index = (n - 1) & root.hash; // 取得根节点在数组中的位置  TreeNode<K,V> first = (TreeNode<K,V>)tab[index]; // 首先取得该位置上的第一个节点对象if (root != first) { // 如果root不是链表上的第一对象 //定义一个变量 	Node<K,V> rn;// 把元素数组index位置的元素替换为根节点对象 tab[index] = root;   
	           // 获取根节点对象的前一个节点TreeNode<K,V> rp = root.prev; if ((rn = root.next) != null) // 如果后节点不为空 ((TreeNode<K,V>)rn).prev = rp; // root后节点的前节点  指向到 root的前节点,相当于把root从链表中摘除!!  // 如果root的前节点不为空if (rp != null) 
	                rp.next = rn; // root前节点的后节点 指向到 root的后节点,到这就说明这个链表就和root无关了 这和上一步是关联操作  就是为了把root找出    if (first != null) // 如果数组该位置上原来的元素不为空first.prev = root; // 这个原有的元素的 前节点 指向到 root,相当于root目前位于链表的首位
	            root.next = first; // 原来的第一个节点现在作为root的下一个节点,变成了第二个节点root.prev = null; // 首节点没有前节点}
	 /*
	         * 这一步是防御性的编程
	         * 校验TreeNode对象是否满足红黑树和双链表的特性
	         * 如果这个方法校验不通过:可能是因为用户编程失误,破坏了结构(例如:并发场景下);也可能是TreeNode的实现有问题(这个是理论上的以防万一);
	         */ assert checkInvariants(root); }}

  /**
         * 递归校验TreeNode对象是否满足红黑树和双链表的特性
         */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;if (tl != null && (tl.parent != t || tl.hash > t.hash))return false;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;}}

标签:TreeNode,17,问答,技术,hashCode,&&,null,root,节点
来源: https://blog.51cto.com/u_12198094/2705340

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有