教你一招:如何获取HashMap的容量capacity和阈值threshold

一、背景

    在深入学习HashMap等集合类的源码时,如果对于动态扩容或初始化的代码理解不透彻,那么我们需要实时监控HashMap的容量capacity以及阈值threshold的变化,这样更能直观的展示出来,便于我们理解源码。话不多说直接上代码!

二、分析

    (1) 代码展示

	public static void main(String[] args) throws Exception {
        //指定初始容量15来创建一个HashMap
		HashMap m = new HashMap(15);
        //获取HashMap整个类
		Class<?> mapType = m.getClass();
        //获取指定属性,也可以调用getDeclaredFields()方法获取属性数组
		Field threshold =  mapType.getDeclaredField("threshold");
        //将目标属性设置为可以访问
		threshold.setAccessible(true);
        //获取指定方法,因为HashMap没有容量这个属性,但是capacity方法会返回容量值
		Method capacity = mapType.getDeclaredMethod("capacity");
        //设置目标方法为可访问
		capacity.setAccessible(true);
        //打印刚初始化的HashMap的容量、阈值和元素数量
		System.out.println("容量:"+capacity.invoke(m)+"    阈值:"+threshold.get(m)+"    元素数量:"+m.size());
		for (int i = 0;i<17;i++){
			m.put(i,i);
            //动态监测HashMap的容量、阈值和元素数量
			System.out.println("容量:"+capacity.invoke(m)+"    阈值:"+threshold.get(m)+"    元素数量:"+m.size());
		}
	}

    就是利用反射的机制,获取HashMap的非public方法capacity()和非public属性threshold。

    (2) 运行结果

    从运行结果图可以看出以下几点:

    * 容量:是取大于等于参数的最小2次幂,如果这个最小二次幂小于16的话也是取值16,这个源码中有写。

    * 阈值:在初始化的时候,阈值是等于容量的;当放入第一个元素后,重新计算阈值,新的阈值=容量X负载因子。

三、总结

     说明阈值并不一直是容量X负载因子,在初始化的时候阈值是等同于容量的。

    

     更多精彩内容,敬请扫描下方二维码,关注我的微信公众号【Java觉浅】,获取第一时间更新哦!

猜你喜欢

转载自blog.csdn.net/qq_34942272/article/details/106423194