如何动态的查看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。
时间: 2024-11-11 17:09:26