资讯专栏INFORMATION COLUMN

初探HashMap之构造方法

fanux / 3555人阅读

摘要:创建时传入初始化容量和负载系数初始化容量顾名思义这个参数定义了这个的初始大小小于零会抛出非法参数异常大于的三十次方则默认等于的三十次方负载因子当你的需要扩容时扩容容量添加方法会用到此方法无符号右移相当于加一做或运算后把值存到左边的变量或运

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 m) {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    putMapEntries(m, false);
}
final void putMapEntries(Map 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 e : m.entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            putVal(hash(key), key, value, false, evict);// 相当于put方法,请看下回分解
        }
    }
}

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67970.html

相关文章

  • JAVA 持有对象——容器初探(持续补充)

    摘要:类库中提供了一套相当完整的容器类来解决这个问题,其中基本类型有,,,,这些对象类型被称为集合类。但是,类库中使用了来指代集合类中的子集,,,所以集合类也被称为容器。五类型是能够将对象映射到其他对象的一种容器,有区别于的方法。 引言 如果一个程序只包含固定数量的且其生命周期都是已知对象,那么这是一个非常简单的程序——《think in java》 了解容器前,先提出一个问题,ArrayL...

    aikin 评论0 收藏0
  • 初探Kotlin+SpringBoot联合编程

    摘要:是一门最近比较流行的静态类型编程语言,而且和一样同属系。这个生成的构造函数是合成的,因此不能从或中直接调用,但可以使用反射调用。 showImg(https://segmentfault.com/img/remote/1460000012958496); Kotlin是一门最近比较流行的静态类型编程语言,而且和Groovy、Scala一样同属Java系。Kotlin具有的很多静态语言...

    xiaokai 评论0 收藏0
  • 初探Java8中的HashMap

    摘要:当冲突的个数比较少时,使用链表,否则使用红黑树。这样做的好处是,最坏的情况下即所有的都冲突,采用链表的话查找时间为而采用红黑树为,这也是中性能提升的奥秘,详细的测试可以看这篇博文。 HashMap是我们最常用的集合之一,同时Java8也提升了HashMap的性能。本着学习的原则,在这探讨一下HashMap。 原理 简单讲解下HashMap的原理:HashMap基于Hash算法,我们...

    William_Sang 评论0 收藏0
  • Android Flux架构初探

    摘要:跟一样,它不是为移动应用设计的,但是它的特性和简单可以让我们很好的在安卓项目中采用。架构在安卓开发中使用设计规范的目的是建立一个在简单性与易扩展易测试之间都比较平衡的架构。第一步是找到元素和安卓组件之间的映射。一个,装载了本次操作。 序言 之前写过一篇关于Android项目如何架构的,有MVC和MCVP,前几天又看到了新的一种架构,当然并不是新出的,出了有一段时间,当前被应用的并不是很...

    blankyao 评论0 收藏0

发表评论

0条评论

fanux

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<