初探HashMap之构造方法

1.创建HashMap时传入初始化容量和负载系数

initialCapacity(初始化容量):顾名思义,这个参数定义了这个HashMap的初始大小;小于零会抛出非法参数异常,大于MAXIMUM_CAPACITY(2的三十次方)则默认等于2的三十次方
loadFactor(负载因子):

public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " +
                                           initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);
}

threshold:当你的HashMap需要扩容时,扩容容量(添加方法put会用到此方法)

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;
}

">>>":无符号右移(相当于加一)
"|="做或运算后把值存到左边的变量("或运算":有1结果为1,全为0结果为0)
为什么要对cap做减1操作?这是为了防止cap已经是2的幂.如果cap已经是2的幂,又没有执行这个减1操作,则执行完后面的几条无符号右移操作之后,返回的capacity将是这个cap的2倍.最后+1,使之成为2的幂
非常牛的一个算法,用于找到大于等于initialCapacity的最小的2的幂(不懂的http://www.th7.cn/Program/jav... 这里不做赘述)

2.创建HashMap时只传入初始化容量
public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

默认负载因子DEFAULT_LOAD_FACTOR = 0.75f

3.创建HashMap时不传入任何参数
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
}
4.创建HashMap时传入一个实现了Map接口的对象,此HashMap创建后会包括此Map的所有内容
public HashMap(Map<? extends K, ? extends V> m) {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    putMapEntries(m, false);
}
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
    int s = m.size();
    if (s > 0) {
        if (table == null) {
            float ft = ((float)s / loadFactor) + 1.0F;
            int t = ((ft < (float)MAXIMUM_CAPACITY) ?
                     (int)ft : MAXIMUM_CAPACITY);
            if (t > threshold)
                threshold = tableSizeFor(t);
        }
        else if (s > threshold) // 传入Map的size大于扩容容量,resize方法为重新初始化一下容量
            resize();
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            putVal(hash(key), key, value, false, evict);// 相当于put方法,请看下回分解
        }
    }
}

table:Node类型,做为空判断是否为新创建.
ft:是否要扩容的操作(为什么+1我现在只有个模糊的感觉,先留个坑)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值