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