HashMap源码中的精妙操作tableSizeFor

本文探讨了HashMap的构造器中关于初始容量和装载因子的设置。装载因子是决定HashMap何时扩容的关键,当元素数量超过容量的75%时,HashMap会进行扩容。作者特别提到了`tableSizeFor(int cap)`方法,这是一个巧妙的计算方式,确保容量始终为2的幂次,从而优化哈希表的性能。通过分析源码,我们可以更好地理解HashMap的内部工作原理。
摘要由CSDN通过智能技术生成

最近看HashMap中的源码,发现了一个精巧的代码,就是初始容量大小的设定

这里是基于JDK 1.8的HashMap,观察一下源码,发现HashMap一共有三个构造器

  • 第1个构造器是两个参数,一个是初始大小initialCapacity,一个是装载因子loadFactor,

  • 第2个构造器是一个参数,初始大小initialCapacity,调用构造方法1,装载因子为0.75

  • 第3个构造器没有参数,构造容量为16,装载因子为0.75

    首先我们讨论一下装载因子loadFactor,这个值的设定是让我们知道HashMap是否需要扩容用的。HashMap有一个确定容量,还有一个属性表示的是HashMap中目前装入了多少数据,如果装入的数据量超过确定容量*装载因子时,HashMap就需要扩容了。例如,当前容量是32,装载因子为0.75,当装入数据量达到24时,HashMap就要进行扩容了。

	/**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and load factor.
     *
     * @param  initialCapacity the initial capacity
     * @param  loadFactor      the load factor
     * @throws IllegalArgumentException if the initial capacity is negative
     *         or the load factor is nonpositive
     */
	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);
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and the default load factor (0.75).
     *
     * @param  initialCapacity the initial capacity.
     * @throws IllegalArgumentException if the initial capacity is negative.
     */
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
     * (16) and the default load factor (0.75).
     */
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }

我主要想说一下的是这里的tableSizeFor(int cap) ,这是一个巧妙的代码,直接就得到大于等于当前数的最小2的幂,就是当前数变成一个最高位开始全为1的二进制数,再加1即可。

	/**
     * Returns a power of two size for the given target capacity.
     */
    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;
    }

位运算的计算过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aurora_98

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值