欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-01 10:45:52
该类方法主要分部在元素的添加(节点树化的相关方法)、查找中,主要涉及以下三个方法:1、comparableClassFor /** * 如果一个对象实现了了Comparable,就返回该类,否则返回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

相关标签: HashMap源码分析