admin管理员组

文章数量:1611559

(Java) ArrayList capacity属性获取+扩容机制验证

capacity私有属性用来描述ArrayList的空间。这里开辟的空间类似于cpp中的malloc,仅仅是开辟,未使用(即未初始化)。

利用反射机制读取私有属性capacity

在java中capacity没有提供相应的get方法。为了得到相应的方法,就需要用到反射。
通过反射机制可以得到相应的Object[]类变量elementData。通过返回其长度就可以得到capacity

ArrayList如何扩容

在cpp中vector是两倍扩容;在java中ArrayList是1.5倍扩容。
在jdk8源码中,其扩容过程实现函数如下:

   private void grow(int minCapacity) {
       // overflow-conscious code
       int oldCapacity = elementData.length;
       int newCapacity = oldCapacity + (oldCapacity >> 1);
       if (newCapacity - minCapacity < 0)
           newCapacity = minCapacity;
       if (newCapacity - MAX_ARRAY_SIZE > 0)
           newCapacity = hugeCapacity(minCapacity);
       // minCapacity is usually close to size, so this is a win:
       elementData = Arrays.copyOf(elementData, newCapacity);
   }

实验代码

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class ArrayListTest {
    private static int getCapacity(List<?> list1) throws NoSuchFieldException, IllegalAccessException {
        Class<ArrayList> arrayListClass = ArrayList.class;
        Field capacity = arrayListClass.getDeclaredField("elementData");
        capacity.setAccessible(true);
        Object[] val = (Object[]) capacity.get(list1);
        return val.length;
    }

    public static void main(String[] args) throws Exception {
        List<Long> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            System.out.printf(list.size() + ",");
            System.out.print(getCapacity(list) + "; ");
            list.add(Long.valueOf((long) i));
        }
    }
}

本文标签: 属性机制JavaArrayListCapacity