如何在Java中获取ArrayList的容量?

时间:2010-03-23 01:56:50

标签: java collections

众所周知,Java ArrayList是使用数组实现的,初始化容量为10,并且其大小增加了50%。如何获取当前ArrayList容量而不是ArrayList的大小。

THX

10 个答案:

答案 0 :(得分:16)

我不认为这是可能的。你的用例是什么?我相信C#ArrayLists具有.capacity属性,但Java ArrayList类不会公开此信息。

您有一个带有初始容量参数的构造函数,并且您可以使用ensureCapacity()方法来减少增量重新分配的数量。

如果你真的担心内存使用,你也可以使用trimToSize()方法。

答案 1 :(得分:9)

你可以通过反思得到它:

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);
        }

    }
}

答案 2 :(得分:2)

查看ArrayList's spec我看不到提供此信息的方法。

也就是说,ensureCapacity方法看起来似乎是朝着正确方向迈出的一步(注意:它不能保证正确的答案):当被调用时,它确保容量是至少指定的参数。因此,如果ArrayList实现使用此方法来确保容量(与调用某些私有方法/直接操作相关字段相反),则可以通过重写此方法来获取当前容量。您还需要以类似的方式覆盖trimToSize()

当然,这个解决方案不是很容易实现,因为ArrayList的不同实现(在来自其他供应商的JVM上)可能会做不同的事情。

以下是代码的外观

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(); }

}

答案 3 :(得分:1)

您可以使用 reflection 获取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

备注:

  1. getCapacity()方法已从原http://javaonlineguide.net/2015/08/find-capacity-of-an-arraylist-in-java-size-vs-capacity-in-java-list-example.html
  2. 修改
  3. 请注意,首次添加到列表后会授予默认容量10。如果您在添加之前尝试此操作,则会获得0
  4. 的输出
  5. 要强制容量而不添加,请在构造函数中传递它,如下所示:

    List<Integer> numbers = new ArrayList<>(20);
    

答案 4 :(得分:0)

不记得它是否有,但你可以通过查看ArrayList的源代码自己完成。 Java开发人员应该利用SDK捆绑的源代码。

答案 5 :(得分:0)

我刚刚查看了ArrayList类的sun文档,我看到的与容量相关的唯一方法是ensureCapacity(int minCapacity),这不是你想要的。祝你好运!

答案 6 :(得分:0)

您可以使用Vector而不是ArrayList。 Vector支持capacity()方法。

答案 7 :(得分:0)

ArrayList的默认容量为10.once达到最大尺寸,新容量为:

新容量=(currentcapacity * 3/2)+1。

答案 8 :(得分:0)

使用ArrayList的重点是动态添加新元素,因此没有特定的方法来获取ArrayList的容量。

每次我们动态添加元素都会导致重新分配,并且由于重新分配在时间上是昂贵的,因此防止重新分配可以提高性能,因此您可以通过调用ensureCapacity()来手动增加ArrayList的容量,但是再次找不到容量的ArrayList。

答案 9 :(得分:0)

java 中数组列表的默认容量为 2。我无法找到我前段时间阅读的模糊文档。但初始化时大小将为零。 一旦我们添加了第三个元素,它将在另一个内存位置创建一个容量翻倍的数组。引用将相应地移动,之前的数组将被垃圾收集