views:

255

answers:

6

Hi, Its known that Java ArrayList is implemented using arrays and initializes with capacity of 10 and increases its size by 50% . How to get the current ArrayList capacity not the Size of the ArrayList.

Thx

+4  A: 

I don't think this is possible. What is your use case? I believe C# ArrayLists have a .capacity property, but the Java ArrayList class doesn't expose this information.

You have the constructor that takes an initial capacity argument, and you have the ensureCapacity() method which you could use to reduce the amount of incremental reallocation.

You also have the trimToSize() method you can use if you are really worried about memory usage.

mbaird
What abt the same case regarding with Vectors ?
JavaUser
Vector has a capacity() method that returns the current capacity. Have you taken the time to look at the API at all? http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html
mbaird
No mbaird , I am just looking into your answer.Thx
JavaUser
A: 

Don't remember if it has but you could do it yourself by looking at the source code of ArrayList. Java developers should take advantage of the source code bundled with the SDK.

instcode
Not sure how useful this would be to help him find the current capacity at runtime though. Unless he took the source and added a method to expose the capacity, and then used his custom version of ArrayList everywhere.
mbaird
Haha, first s.o upvote then s.o else downvote :)) I gave him a rod but you gave him a fish... Now what, he gonna ask for Vector, LinkedList..? :))
instcode
A: 

I just checked out the sun documentation on the ArrayList class, and the only method I saw that related to the capacity was ensureCapacity(int minCapacity), which is not exactly what you want. Good luck!

chama
+1  A: 

Looking at ArrayList's spec I see no method that provides this information.

That said, the ensureCapacity method does seem like a step in the right direction (caution: it is does not guarantee a correct answer): When called it ensures that the capacity is at least the specified argument. So, if the ArrayList implementation uses this method to ensure capacity (as opposed to calling some private method/manipulating the relevant fields directly) you can obtain the current capacity by overriding this method. You also need to override trimToSize() in a similar manner.

Of course, this solution is not very portable as a different implementation of ArrayList (on a JVM from another vendor) may do things differently.

Here's how the code should look like

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

}
Itay
ensureCapacity() just ensures that it has at least that much space. If it has more space it will do nothing. If later you keep adding elements so that it needs even more, it will grow. None of these cases would be handled by your example code. All your code will do is allow you to be reminded of what value you passed to ensureCapacity() earlier, which may have no real bearing on what the true capacity is later on.
mbaird
By all means, I don't say this is a perfect solution nor is it a portable one. It is just a step in the right direction.
Itay
A: 

You can get it by reflection:

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

    }
}
pgras
This will fail horribly, when the field is not called `elementData`. And since that name is not specified in the API, any implementation (and any version!) is free to call it something else entirely.
Joachim Sauer
+1  A: 

How to get the current ArrayList capacity not the Size of the ArrayList.

Why exactly would you ever need to know?

EJP