HashMap源码 1

  • DEFAULT_INITIAL_CAPACITY 1 << 4;    初始化容量为16,必须是2的幂
  • MAXIMUM_CAPACITY 1 << 30;    最大容量为2的30次方
  • DEFAULT_LOAD_FACTOR = 0.75;    默认加载因子0.75,因此初始情况下,当键值对的数量大于 16 * 0.75 = 12 时,就会触发扩容
  • TREEIFY_THRESHOLD = 8;    由链表转换成树的阈值,当某个箱子中,链表长度大于 8 时,有可能会转化成树
  • UNTREEIFY_THRESHOLD = 6;    由树转换成链表的阈值,在哈希表扩容时,如果发现链表长度小于 6,则会由树重新退化为链表
  • MIN_TREEIFY_CAPACITY = 64;   在转变成树之前,还会有一次判断,只有键值对数量大于 64 才会发生转换
  1. Node静态内部类:
    Node<K,V>实现了Map的内部接口Map.Entry<K,V>,它表示Map中的一个实体(一个key-value对)
    提供了getKey();getValue();hashCode();setValue(V newValue);equals(Object o);等方法
    注意,在Node中成员变量hash是指key对应的hash值
    其成员方法hashCode为node对象的hash值
    在成员变量table中引用的就是这个Node
  2. static final int hash(Object key):
    static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);    // key为空,返回0,否则返回原hash值和原hash值无符号右移16位的值按位异或的结果
        }

    由于覆盖equals()需要覆盖hashCode(),所以hashCode()有时并不十分完美,比如只和高位有关等等,因此需要再hash()一下
    方法在JDK1.8中保证了对象的hashCode的高16位的变化能反应到低16位中,相比较而言减少了过多的位运算
  3. static Class<?> comparableClassFor(Object x):
    当传入对象的运行时类型符合”class C implements Comparable”这个条件时,返回对象的运行时类型,否则返回null

    static Class<?> comparableClassFor(Object x) {

            if (x instanceof Comparable) {    // 判断是否实现了Comparable
                Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
                if ((c = x.getClass()) == String.class) // bypass checks
                    return c;    // 如果是String类型,则直接返回
                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) &&    // 该类是Comparable类型
                            (as = p.getActualTypeArguments()) != null &&    // 获取泛型参数类型数组
                            as.length == 1 && as[0] == c) // type arg is c    // 只有1个泛型参数,并且该实现是该类本身
                            return c;    // 返回该类
                    }
                }
            }
            return null;
        }

  4. ParameterizedType:
    getActualTypeArguments()
        返回 这个 Type 类型的参数的实际类型数组。 如 Map<String,Person> map 这个 ParameterizedType 返回的是 String 类,Person 类的全限定类名的 Type Array    (获取该类实现的泛型类"<>"内的类型)
    getClass().getGenericInterfaces()
        返回表示某些接口的 Type,这些接口由此对象所表示的类或接口直接实现    (获取该类实现的接口的全路径名)
    getRawType() 
        返回的是当前这个 ParameterizedType 的类型。如 Map<String,Person> map这个ParameterizedType返回的是Map类的全限定类名的Type Array()    (获取该类实现的泛型类的全限定名)
  5. static int compareComparables(Class<?> kc, Object k, Object x):
    判断x是否为空,并且x是否为kc类型,如果为真,则使用((Comparable)k).compareTo(x)),进行大小比较,否则返回0
  6. static final int tableSizeFor(int cap):
    (不考虑大于最大容量的情况)是返回大于输入参数且最近的2的整数次幂的数。比如10,则返回16
    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;
        }
    有关n位操作部分:先来假设n的二进制为01xxx...xxx
    对n右移1位:001xx...xxx,再位或:011xx...xxx
    对n右移2为:00011...xxx,再位或:01111...xxx
    此时前面已经有四个1了,再右移4位且位或可得8个1
    同理,有8个1,右移8位肯定会让后八位也为1
    综上可得,该算法让最高位的1后面的位全变为1
    最后再让结果n+1,即得到了2的整数次幂的值了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值