標籤:
如何動態查看ArrayList的容量?
在ArrayList提供的方法中,有三個方法:
size() -- 返回當前列表中的元素數量;
trimToSize() -- 將當前ArrayList容量調整為列表的當前大小;
ensureCapacity(int minCapacity) -- 如果需要擴充列表的容量以確保能夠裝下minCapacity個元素;
那如何動態監控整個列表的容量變化?
請參考如下代碼:
import java.lang.reflect.Field;
import java.util.ArrayList;public class ArraySizeTest { @SuppressWarnings("rawtypes") public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<String> testArray = new ArrayList<String>(5); Field AL_Field; Field AL_Field_1; Field AL_Field_2; Field AL_Field_3; try { //check the initial capacity of testArray Class AL_Class = testArray.getClass(); AL_Field = AL_Class.getDeclaredField("elementData"); AL_Field.setAccessible(true); Object[] objects = (Object[]) AL_Field.get(testArray); System.out.println(objects.length); System.out.println(testArray.size()); //result: capacity = 5, size = 0; //add 4 items in the testArray System.out.println("1::> " + testArray.hashCode()); for(int i=0; i<4; i++){
testArray.add(i, Integer.toString(i));
System.out.println("1."+i+"::> " + testArray.hashCode()); } System.out.println(objects.length); System.out.println(testArray.size()); System.out.println("2::> " + testArray.hashCode()); //result: capacity = 5, size = 4; //result: new a ArrayList //after trimToSize testArray.trimToSize(); //re-get the objects Class AL_Class_1 = testArray.getClass(); AL_Field_1 = AL_Class_1.getDeclaredField("elementData"); AL_Field_1.setAccessible(true); Object[] objects_1 = (Object[]) AL_Field_1.get(testArray); System.out.println(objects_1.length); System.out.println(testArray.size()); //result: capacity = 4, size = 4; //larger the capacity to 6 System.out.println("3::> " + testArray.hashCode()); testArray.ensureCapacity(6); testArray.add("5"); testArray.add("6"); testArray.add("7"); System.out.println("4::> " + testArray.hashCode()); //after adding item the testArray is re-created //re-get the objects Class AL_Class_2 = testArray.getClass(); AL_Field_2 = AL_Class_2.getDeclaredField("elementData"); AL_Field_2.setAccessible(true); Object[] objects_2 = (Object[]) AL_Field_2.get(testArray); System.out.println(objects_2.length); System.out.println(testArray.size()); System.out.println("5::> " + testArray.hashCode()); //result: capacity = 9, size = 7; //do not create a new ArrayList testArray.trimToSize(); //re-get objects Class AL_Class_3 = testArray.getClass(); AL_Field_3 = AL_Class_3.getDeclaredField("elementData"); AL_Field_3.setAccessible(true); Object[] objects_3 = (Object[]) AL_Field_3.get(testArray); System.out.println(objects_3.length); System.out.println(testArray.size()); System.out.println("6::> " + testArray.hashCode()); //result: capacity = 7, size = 7; //result: do not create a new ArrayList } catch (NoSuchFieldException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
結果:
5
0
1::>1
1.0::>79
1.1::>2498
1.2::>77488
1.3::>2402179
5
4
2::>2402179
4
4
3::>2402179
4::>-1451076781
9
7
5::>-1451076781
7
7
6::>-1451076781
從代碼中可以看出:
ArrayList每次在追加item之後都在重新建立一個ArrayList對象,直到運用ensureCapacity方法。
雖然我們設定了最大長度為6,但是當追加的內容數目超出6之後,隨著size的增大,ArrayList的容量在變大,具體變大多少從本例中看到的是2,我也嘗試過追加內容,增大原則大致是2,3,5,8,13...(i = (i-1)+(i-2))。
另外需要注意的是在每次利用反射找出ArrayList的容量後對ArrayList修改,下次再要進行容量計算時需要重新做Object Get。
Java Learning(5) -- ArrayList