關於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
注意:沒有擴容

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章