众所周知,Java ArrayList 使用数组实现,并以容量为10进行初始化,每次增加50%。如何获取当前 ArrayList 的容量而不是大小。
谢谢。
众所周知,Java ArrayList 使用数组实现,并以容量为10进行初始化,每次增加50%。如何获取当前 ArrayList 的容量而不是大小。
谢谢。
我认为这是不可能的。你有什么使用场景?我相信C# ArrayLists 有一个 .capacity
属性,但Java ArrayList类没有公开这个信息。
你可以使用带有初始容量参数的构造函数,也可以使用 ensureCapacity()
方法来减少增量重新分配的次数。
如果您真的担心内存使用情况,您还可以使用 trimToSize()
方法。
你可以通过反射来获取它:
public abstract class ArrayListHelper {
static final Field field;
static {
try {
field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
@SuppressWarnings("unchecked")
public static <E> int getArrayListCapacity(ArrayList<E> arrayList) {
try {
final E[] elementData = (E[]) field.get(arrayList);
return elementData.length;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
elementData
,这将会失败得非常惨。而且因为API没有指定这个名字,所以任何实现(以及任何版本!)都可以将其命名为完全不同的名称。 - Joachim Sauer您可以使用反射在Java中获取ArrayList的当前容量。以下是一个示例:
package examples1;
import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Field;
public class Numbers {
public static void main(String[] args) throws Exception {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
System.out.println(getCapacity(numbers));
}
static int getCapacity(List al) throws Exception {
Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
return ((Object[]) field.get(al)).length;
}
}
10
注释:
getCapacity()
method modified from the original at http://javaonlineguide.net/2015/08/find-capacity-of-an-arraylist-in-java-size-vs-capacity-in-java-list-example.html0
To force a capacity without adding, pass it in the constructor like so:
List<Integer> numbers = new ArrayList<>(20);
查看ArrayList的规范,我没有看到提供此信息的方法。
话虽如此,ensureCapacity方法似乎是朝着正确方向迈出的一步(注意:它不能保证正确答案):当调用它时,它确保容量至少为指定参数。因此,如果ArrayList
实现使用此方法来确保容量(而不是调用某些私有方法/直接操作相关字段),则可以通过覆盖此方法来获取当前容量。您还需要以类似的方式覆盖trimToSize()
。
当然,这种解决方案在可移植性方面并不是很好,因为不同供应商的JVM上的ArrayList
实现可能会有所不同。
以下是代码示例:
public class CapacityTrackingArrayList<T> extends ArrayList<T> {
// declare a constructor for each ArrayList constructor ...
// Now, capacity tracking stuff:
private int currentCapacity = 10;
public int getCapacity() { return currentCapacity; }
public void ensureCapacity(int arg) {
currentCapacity = arg;
super.ensureCapacity(arg);
}
public void trimToSize() { currentCapacity = size(); super.trimToSize(); }
}
ArrayList
的默认容量为10。一旦达到最大大小,新的容量将会是:
新容量=(当前容量*3/2)+1。
ArrayList
的容量,而不是一个Vector
。 - Manuel不记得是否有,但你可以通过查看ArrayList的源代码自己完成。Java开发人员应该利用与SDK捆绑的源代码。