首页 > 程序开发 > 软件开发 > 其他 >

JDK8:HashMap源码解析之comparableClassFor方法

2018-06-15

JDK8:HashMap源码解析之comparableClassFor方法。

一、概述

在之前的文章里已经分析过,在发生hash碰撞(多个key的hash值相同)的时候,hashMap首先会采用链表进行存储,当链表节点数量达到一定阈值(8)会将链表上的节点再组织成一棵红黑树。红黑树是一种二叉树,每个父节点可以由左右两个节点。

当put一个新元素时,如果该元素键的hash值小于当前节点的hash值的时候,就会作为当前节点的左节点;hash值大于当前节点hash值得时候作为当前节点的右节点。那么hash值相同的时候呢?这时还是会先尝试看是否能够通过Comparable进行比较一下,要想看看是否能基于Comparable进行比较的话,首先要看该元素键是否实现了Comparable接口,此时就需要用到comparableClassFor方法来获取该元素键的Class。

二、方法解析

/**
* 如果对象x的类是C,如果C实现了Comparable接口,那么返回C,否则返回null
*/
static Class comparableClassFor(Object x) {
 if (x instanceof Comparable) {
  Class c; Type[] ts, as; Type t; ParameterizedType p;
  if ((c = x.getClass()) == String.class) // 如果x是个字符串对象
return c; // 返回String.class
  /*
* 为什么如果x是个字符串就直接返回c了呢 ? 因为String  实现了 Comparable 接口,可参考如下String类的定义
* public final class String implements java.io.Serializable, Comparable, CharSequence
*/ 

  // 如果 c 不是字符串类,获取c直接实现的接口(如果是泛型接口则附带泛型信息) 
  if ((ts = c.getGenericInterfaces()) != null) {
for (int i = 0; i < ts.length; ++i) { // 遍历接口数组
 // 如果当前接口t是个泛型接口 
 // 如果该泛型接口t的原始类型p 是 Comparable 接口
 // 如果该Comparable接口p只定义了一个泛型参数
 // 如果这一个泛型参数的类型就是c,那么返回c
 if (((t = ts[i]) instanceof ParameterizedType) &&
  ((p = (ParameterizedType)t).getRawType() ==
Comparable.class) &&
  (as = p.getActualTypeArguments()) != null &&
  as.length == 1 && as[0] == c) // type arg is c
  return c;
}
// 上面for循环的目的就是为了看看x的class是否 implements  Comparable
  }
 }
 return null; // 如果c并没有实现 Comparable 那么返回空
}
相关文章
最新文章
热点推荐