当前位置: 移动技术网 > IT编程>开发语言>Java > 1、JDK1.8HashMap源码分析系列文章(comparableClassFor、compareComparables、tieBreakOrder)

1、JDK1.8HashMap源码分析系列文章(comparableClassFor、compareComparables、tieBreakOrder)

2020年07月31日  | 移动技术网IT编程  | 我要评论
该类方法主要分部在元素的添加(节点树化的相关方法)、查找中,主要涉及以下三个方法:1、comparableClassFor /** * 如果一个对象实现了了Comparable<C>,就返回该类,否则返回null * * @param x 需要判断的对象 * @return java.lang.Class<?> * @Author muyi * @Dat

该类方法主要分部在元素的添加(节点树化的相关方法)、查找中,主要涉及以下三个方法:

1、comparableClassFor

        /**
         * 如果一个对象实现了了Comparable<C>,就返回该类,否则返回null
         *
         * @param x 需要判断的对象
         * @return java.lang.Class<?>
         * @Author muyi
         * @Date 15:54 2020/7/30
         */
        static Class<?> comparableClassFor(Object x) {
            if (x instanceof Comparable) {
                Class<?> c;
                Type[] ts, as;
                Type t;
                ParameterizedType p;
                // 由于String实现了Comparable接口
                if ((c = x.getClass()) == String.class)
                    return c;
                // getGenericInterfaces()方法返回的是该对象的运行时类型“直接实现”的接口,继承过来的不算
                if ((ts = c.getGenericInterfaces()) != null) {
                    for (int i = 0; i < ts.length; ++i) {
                        /**
                         * 五个条件同时满足时,才获取到正确的类型
                         * 1、((t = ts[i]) instanceof ParameterizedType):实现了泛型参数的类型
                         * 2、((p = (ParameterizedType) t).getRawType() == Comparable.class):获取接口不带参数部分的类型对象且该类型是Comparable
                         * 3、(as = p.getActualTypeArguments()):获取泛型参数数组
                         * 4、as.length == 1:只有一个泛型参数,
                         * 5、as[0] == c:该实现类型是该类型本身
                         * 这里,我是这样理解的,Comparable只有一个泛型参数,且就是实现的本身,故需要对4、5条件进行判断
                         */
                        if (((t = ts[i]) instanceof ParameterizedType) &&
                                ((p = (ParameterizedType) t).getRawType() ==
                                        Comparable.class) &&
                                (as = p.getActualTypeArguments()) != null &&
                                as.length == 1 && as[0] == c)
                            return c;
                    }
                }
            }
            return null;
        }

2、compareComparables

        /**
         * 比较两个对象的大小
         * 注意:在源文件中调用这个方法的地方,已确定kc肯定不为null,
         * @param kc 已知k的Class
         * @param k 对象
         * @param x 对象
         * @return int,当为NULL的,返回0,是因为在红黑树中,空节点
         * @Author muyi
         * @Date 16:00 2020/7/30
         */
        static int compareComparables(Class<?> kc, Object k, Object x) {
            return (x == null || x.getClass() != kc ? 0 :
                    ((Comparable) k).compareTo(x));
        }

3、tieBreakOrder

        /**
         * 比较两个对象的大小,该方法返回值绝对不会等于0
         *
         * @param a
         * @param b
         * @return
         */
        static int tieBreakOrder(Object a, Object b) {
            int d;
            if (a == null || b == null ||
                    // 比较两个类的名字是否相等
                    (d = a.getClass().getName().
                            compareTo(b.getClass().getName())) == 0)
                // System.identityHashCode(a):返回对象的默认hashCode,空对象的默认hashCode=0
                d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
                        -1 : 1);
            return d;
        }

 

本文地址:https://blog.csdn.net/qq_40722604/article/details/107692380

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网