HashMap源码之其余

/**
* 计算hash方法
* 这里之因此没有直接使用key的hash.是为了应对当key的hash分布很是差的时候,会间接致使
* hash桶的分布很是差,从而影响性能.因此使用原hash异或(XOR)原hash的高16位,做为实际使用的hash
* 这里之因此使用16:16,而不是8:8:8:8或其余值,是由于jdk开发者充分考虑了时间,效率,性能等各方面
* 的状况后的折中选择.
* 同时也是由于当前jdk大多数的hash已经有了较好的分布,因此也不须要进行过多的处理
* 计算过程以下
* 10000000000000000000000000000000
* 00000000000000001000000000000000
* 10000000000000001000000000000000
*/
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

/**
 * 当对象x(key)存在如class C implements Comparable<C>的实现时,返回x的类型
 * 这里主要验证了Comparable<C>部分,防止在后续比较中调用Comparable.compareTo(T t)方法调用失败
 */
static Class<?> comparableClassFor(Object x) {
    if (x instanceof Comparable) {
        Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
        if ((c = x.getClass()) == String.class) // bypass checks
            return c;
        if ((ts = c.getGenericInterfaces()) != null) {
            for (int i = 0; i < ts.length; ++i) {
                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;
            }
        }
    }
    return null;
}

/**Comparable
* 在comparableClassFor方法后调用,已经肯定k实现了Comparable接口
* kc是k的类型(多是一个实现了Comparable的类型)
* 若是x的类型与k的类型不相等,返回0.不然返回compare的结果
* 注: 这里有一个特别的地方,就是x.getClass() != kc部分.当节点的各键类型不一样时,即
* 使他们k实现了Comparable接口,也不会调用
*/
static int compareComparables(Class<?> kc, Object k, Object x) {
    return (x == null || x.getClass() != kc ? 0 :
            ((Comparable)k).compareTo(x));
}

/**
 * 计算一个大于输入值的最小的2次幂.
 * 直接上流程(暂时忽略cap - 1部分,最后说)
 * 10000    16  n初始状态
 * 11000    24  n|=n>>>1 等价于 n = 10000|01000 = 11000
 * 11110    30  n|=n>>>2 等价于 n = 11000|00110 = 11110
 * 11111    31  n|=n>>>4 等价于 n = 11110|00001 = 11111
 * 11111    31  略
 * 11111    31  略
 * 100000   32  n+1
 * 最后,经过+1,将...111变为100...,即2的n次幂
 * 
 * 这里使用了一个颇有意思的方式完成了工做,就是输入值的最高有效位.
 * 经过不断的向低位复制最高有效位(1),将全部低位换为1,最终这个值等于(2^n)-1.同时
 * 也是当前数字的最高位能表达的最大值
 * 那么,再对这个值+1就可使这个值变成2^n.也就是大于输入值的最小的2的幂
 * 
 * cap - 1的做用:
 * 若是输入值已是2的幂,那么这个方法应该直接返回他.直接进行-1,使用原逻辑便可
 * 
 */
static final int tableSizeFor(int cap) {
    int n = cap - 1;
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
相关文章
相关标签/搜索