• 关于HashMap、HashSet和ArrayList集合对象容量初始值设置及扩容演示


    ArrayList:
    -------------------------------------
    明确知道容量:直接设置初始容量,如new ArrayList<>(100)
    无法确定容量:预估一个比较接近的值,如果实在无法确定,则无需指定初始值 (有默认值)
    ArrayList没有加载因子,初始容量10,扩容增量为原来的0.5倍取整


    HashMap(HashSet规则相同)
    -------------------------------------
    HashMap的默认加载因子为0.75,但可以使用构造器指定,如new HashMap<>(100, 1),此时指定加载因子为1
    故计算HashMap的初始值时的工式为:(int) (realSize / loadFactor) + 1
    如果实际容量为100,加载因子为默认(0.75),计算容量为:(int) (100 / 0.75) + 1 = 134,则实例化HashMap为 new HashMap<>(134)
    如果实际容量为100,加载因子1,则计算工式为:(int) (100 / 1) + 1 = 101,则则实例化HashMap为 new HashMap<>(101, 1)
    HashMap、HashMap加载因子0.75,初始容量16,扩容增量为原来的1倍
    注意:加载因子越大节省内存但查找效率低,加载因子越小耗内存但查找效率高,系统默认加载因子为0.75,一般情况下我们是无需修改的。

    以上单元测试HashMap、ArrayList持续增加元素及扩容情况:

        @Test
        public void testHashMapResize() throws Exception {
            System.out.println("-------- 开始测试HashMap --------");
            System.out.println("不设置 initCapacity");
            this.testHashMapResizeProfile(0);
            System.out.println("");
            System.out.println("initCapacity 为 25");
            this.testHashMapResizeProfile(25);
            System.out.println("");
            System.out.println("initCapacity 为 34");
            this.testHashMapResizeProfile(34);
    
            System.out.println();
            System.out.println("-------- 开始测试ArrayList --------");
            System.out.println("不设置 initCapacity");
            this.testArrayListResizeProfile(0);
            System.out.println("");
            System.out.println("initCapacity 为 25");
            this.testArrayListResizeProfile(25);
        }
    
        /**
         * 以循环添加25个元素测试扩容。
         * @param initCapacity 初始容量
         * @throws Exception
         */
        private void testHashMapResizeProfile(int initCapacity) throws Exception {
            Map<String, String> map = null;
            if (initCapacity <= 0) {
                map = new HashMap();
            } else {
                map = new HashMap(initCapacity);
            }
    
            Field threshold = map.getClass().getDeclaredField("threshold");
            Field size = map.getClass().getDeclaredField("size");
            Method capacity = map.getClass().getDeclaredMethod("capacity");
    
            threshold.setAccessible(true);
            size.setAccessible(true);
            capacity.setAccessible(true);
    
            // 临界值、容量测试
            for (int i = 1; i <= 25; i++) {
                map.put(String.valueOf(i), i + "**");
                System.out.println("第" + i + "个对象, size为" + size.get(map) + ", threshold为" + threshold.get(map) + ", capacity容量为" + capacity.invoke(map));
            }
        }
    
        /**
         * 以循环添加25个元素测试扩容。
         * @param initCapacity 初始容量
         * @throws Exception
         */
        private void testArrayListResizeProfile(int initCapacity) throws Exception {
            ArrayList<String> list = null;
            if (initCapacity <= 0) {
                list = new ArrayList();
            } else {
                list = new ArrayList(initCapacity);
            }
    
            Field size = list.getClass().getDeclaredField("size");
            Field elementData = list.getClass().getDeclaredField("elementData");
    
            size.setAccessible(true);
            elementData.setAccessible(true);
    
            // 临界值、容量测试
            for (int i = 1; i <= 25; i++) {
                list.add(String.valueOf(i));
                System.out.println("第" + i + "个对象, size为:" + size.get(list) + ", 扩容后容量为:" + ((Object[])elementData.get(list)).length);
            }
        }

    以下为HashMap持续增加元素及扩容输出:

    不设置 initCapacity
    第1个对象, size为1, threshold为12, capacity容量为16
    第2个对象, size为2, threshold为12, capacity容量为16
    第3个对象, size为3, threshold为12, capacity容量为16
    第4个对象, size为4, threshold为12, capacity容量为16
    第5个对象, size为5, threshold为12, capacity容量为16
    第6个对象, size为6, threshold为12, capacity容量为16
    第7个对象, size为7, threshold为12, capacity容量为16
    第8个对象, size为8, threshold为12, capacity容量为16
    第9个对象, size为9, threshold为12, capacity容量为16
    第10个对象, size为10, threshold为12, capacity容量为16
    第11个对象, size为11, threshold为12, capacity容量为16
    第12个对象, size为12, threshold为12, capacity容量为16
    第13个对象, size为13, threshold为24, capacity容量为32
    第14个对象, size为14, threshold为24, capacity容量为32
    第15个对象, size为15, threshold为24, capacity容量为32
    第16个对象, size为16, threshold为24, capacity容量为32
    第17个对象, size为17, threshold为24, capacity容量为32
    第18个对象, size为18, threshold为24, capacity容量为32
    第19个对象, size为19, threshold为24, capacity容量为32
    第20个对象, size为20, threshold为24, capacity容量为32
    第21个对象, size为21, threshold为24, capacity容量为32
    第22个对象, size为22, threshold为24, capacity容量为32
    第23个对象, size为23, threshold为24, capacity容量为32
    第24个对象, size为24, threshold为24, capacity容量为32
    第25个对象, size为25, threshold为48, capacity容量为64
    注意:扩容2次
    
    initCapacity 为 25
    第1个对象, size为1, threshold为24, capacity容量为32
    第2个对象, size为2, threshold为24, capacity容量为32
    第3个对象, size为3, threshold为24, capacity容量为32
    第4个对象, size为4, threshold为24, capacity容量为32
    第5个对象, size为5, threshold为24, capacity容量为32
    第6个对象, size为6, threshold为24, capacity容量为32
    第7个对象, size为7, threshold为24, capacity容量为32
    第8个对象, size为8, threshold为24, capacity容量为32
    第9个对象, size为9, threshold为24, capacity容量为32
    第10个对象, size为10, threshold为24, capacity容量为32
    第11个对象, size为11, threshold为24, capacity容量为32
    第12个对象, size为12, threshold为24, capacity容量为32
    第13个对象, size为13, threshold为24, capacity容量为32
    第14个对象, size为14, threshold为24, capacity容量为32
    第15个对象, size为15, threshold为24, capacity容量为32
    第16个对象, size为16, threshold为24, capacity容量为32
    第17个对象, size为17, threshold为24, capacity容量为32
    第18个对象, size为18, threshold为24, capacity容量为32
    第19个对象, size为19, threshold为24, capacity容量为32
    第20个对象, size为20, threshold为24, capacity容量为32
    第21个对象, size为21, threshold为24, capacity容量为32
    第22个对象, size为22, threshold为24, capacity容量为32
    第23个对象, size为23, threshold为24, capacity容量为32
    第24个对象, size为24, threshold为24, capacity容量为32
    第25个对象, size为25, threshold为48, capacity容量为64
    注意:扩容1次
    
    initCapacity 为 34   (int) (25 / 0.75) + 1 = 34
    第1个对象, size为1, threshold为48, capacity容量为64
    第2个对象, size为2, threshold为48, capacity容量为64
    第3个对象, size为3, threshold为48, capacity容量为64
    第4个对象, size为4, threshold为48, capacity容量为64
    第5个对象, size为5, threshold为48, capacity容量为64
    第6个对象, size为6, threshold为48, capacity容量为64
    第7个对象, size为7, threshold为48, capacity容量为64
    第8个对象, size为8, threshold为48, capacity容量为64
    第9个对象, size为9, threshold为48, capacity容量为64
    第10个对象, size为10, threshold为48, capacity容量为64
    第11个对象, size为11, threshold为48, capacity容量为64
    第12个对象, size为12, threshold为48, capacity容量为64
    第13个对象, size为13, threshold为48, capacity容量为64
    第14个对象, size为14, threshold为48, capacity容量为64
    第15个对象, size为15, threshold为48, capacity容量为64
    第16个对象, size为16, threshold为48, capacity容量为64
    第17个对象, size为17, threshold为48, capacity容量为64
    第18个对象, size为18, threshold为48, capacity容量为64
    第19个对象, size为19, threshold为48, capacity容量为64
    第20个对象, size为20, threshold为48, capacity容量为64
    第21个对象, size为21, threshold为48, capacity容量为64
    第22个对象, size为22, threshold为48, capacity容量为64
    第23个对象, size为23, threshold为48, capacity容量为64
    第24个对象, size为24, threshold为48, capacity容量为64
    第25个对象, size为25, threshold为48, capacity容量为64
    注意:未扩容
    

    以下为ArrayList持续增加元素及扩容输出:

    不设置 initCapacity
    第1个对象, size为:1, 扩容后容量为:10
    第2个对象, size为:2, 扩容后容量为:10
    第3个对象, size为:3, 扩容后容量为:10
    第4个对象, size为:4, 扩容后容量为:10
    第5个对象, size为:5, 扩容后容量为:10
    第6个对象, size为:6, 扩容后容量为:10
    第7个对象, size为:7, 扩容后容量为:10
    第8个对象, size为:8, 扩容后容量为:10
    第9个对象, size为:9, 扩容后容量为:10
    第10个对象, size为:10, 扩容后容量为:10
    第11个对象, size为:11, 扩容后容量为:15
    第12个对象, size为:12, 扩容后容量为:15
    第13个对象, size为:13, 扩容后容量为:15
    第14个对象, size为:14, 扩容后容量为:15
    第15个对象, size为:15, 扩容后容量为:15
    第16个对象, size为:16, 扩容后容量为:22
    第17个对象, size为:17, 扩容后容量为:22
    第18个对象, size为:18, 扩容后容量为:22
    第19个对象, size为:19, 扩容后容量为:22
    第20个对象, size为:20, 扩容后容量为:22
    第21个对象, size为:21, 扩容后容量为:22
    第22个对象, size为:22, 扩容后容量为:22
    第23个对象, size为:23, 扩容后容量为:33
    第24个对象, size为:24, 扩容后容量为:33
    第25个对象, size为:25, 扩容后容量为:33
    注意:扩容2次
    initCapacity 为 25
    第1个对象, size为:1, 扩容后容量为:25
    第2个对象, size为:2, 扩容后容量为:25
    第3个对象, size为:3, 扩容后容量为:25
    第4个对象, size为:4, 扩容后容量为:25
    第5个对象, size为:5, 扩容后容量为:25
    第6个对象, size为:6, 扩容后容量为:25
    第7个对象, size为:7, 扩容后容量为:25
    第8个对象, size为:8, 扩容后容量为:25
    第9个对象, size为:9, 扩容后容量为:25
    第10个对象, size为:10, 扩容后容量为:25
    第11个对象, size为:11, 扩容后容量为:25
    第12个对象, size为:12, 扩容后容量为:25
    第13个对象, size为:13, 扩容后容量为:25
    第14个对象, size为:14, 扩容后容量为:25
    第15个对象, size为:15, 扩容后容量为:25
    第16个对象, size为:16, 扩容后容量为:25
    第17个对象, size为:17, 扩容后容量为:25
    第18个对象, size为:18, 扩容后容量为:25
    第19个对象, size为:19, 扩容后容量为:25
    第20个对象, size为:20, 扩容后容量为:25
    第21个对象, size为:21, 扩容后容量为:25
    第22个对象, size为:22, 扩容后容量为:25
    第23个对象, size为:23, 扩容后容量为:25
    第24个对象, size为:24, 扩容后容量为:25
    第25个对象, size为:25, 扩容后容量为:25
    注意:没有扩容
    

     

     

  • 相关阅读:
    Hibernate 实体关联关系映射----总结
    原型模式(Prototype)解析例子
    Java 泛型的理解与等价实现
    Java:对象创建和初始化过程
    iReport的简单配置
    Python语言程序设计基础(第2版)课后习题答案 嵩天、礼欣、黄天羽版 高等教育出版社 试题和答案和解析
    编程精品教材:MATLAB程序设计与应用(第3版) 课后答案 刘卫国版 课后习题答案解析
    SkyWalking 快速接入实践
    Java基础 day01【前言、入门程序、常量、变量】
    python最新笔试题
  • 原文地址:https://www.cnblogs.com/mrhgw/p/12198156.html
Copyright © 2020-2023  润新知