37

Possible Duplicate:
How to get the capacity of the ArrayList in Java?

How to find the capacity of an ArrayList?

Community
  • 1
  • 1
user430532
  • 371
  • 1
  • 3
  • 3
  • Unfortunately not part of the API, but a bit annoying how many people in the answers are either not answering the question or answering the wrong question. – nathanfranke Oct 12 '20 at 02:45
  • You can't without a reflection hack, ArrayList doesn't support capacity ordinarily. If you need this data, just use a Vector instead – egerardus Jan 30 '21 at 17:33

8 Answers8

87

I'm curious, what do you need it for? You should know that the capacity is not (as it may sound) an upper limit of how much you can put into the ArrayList. It's a value representing how much data you can put into the list, without forcing it to reallocate it internal array. Basically, the notion of capacity is only there in order for you to tweak the performance slightly.

Anyway, perhaps you already know that, so here comes the actual answer.

The interface provided by API for ArrayList simply doesn't support such use case. There are many reasons for this. One reason is that you shouldn't care about this. The ArrayList is to be thought of as an unbounded array which abstracts away from details such as capacity.

The closest you can get to controlling the capacity is through the constructor ArrayList(int initialCapacity), and the two methods trimToSize() and ensureCapacity(int minCapacity).

For fun however, I managed to solve it through an ugly reflection-hack (don't use this):

import java.lang.reflect.Field;
import java.util.ArrayList;
public class Test {

    public static void main(String[] args) throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>(3);
        for (int i = 0; i < 17; i++) {
            list.add(i);
            System.out.format("Size: %2d, Capacity: %2d%n",
                              list.size(), getCapacity(list));
        }
    }

    static int getCapacity(ArrayList<?> l) throws Exception {
        Field dataField = ArrayList.class.getDeclaredField("elementData");
        dataField.setAccessible(true);
        return ((Object[]) dataField.get(l)).length;
    }
}

Output:

Size:  1, Capacity:  3
Size:  2, Capacity:  3
Size:  3, Capacity:  3
Size:  4, Capacity:  5
Size:  5, Capacity:  5
Size:  6, Capacity:  8
Size:  7, Capacity:  8
Size:  8, Capacity:  8
Size:  9, Capacity: 13
Size: 10, Capacity: 13
Size: 11, Capacity: 13
Size: 12, Capacity: 13
Size: 13, Capacity: 13
Size: 14, Capacity: 20
Size: 15, Capacity: 20
Size: 16, Capacity: 20
Size: 17, Capacity: 20
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 4
    I am tempted to vote this down, even 'though it is correct, in-depth and warns of the dangers of trying to circumvent it, just because it provides code for the ugly hack ... – Joachim Sauer Aug 25 '10 at 12:07
  • 19
    Sure, it should be emphasized that this method should not be used in production code. It *could* however be the case that someone wishes to, for instance, debug some performance issue or similar, in which case the above code-snippet may be useful. But as I wrote in the answer, I implemented it for fun and it shouldn't really be used in 99% of the cases. – aioobe Aug 25 '10 at 12:42
  • @aiobee nice hack :) To make your answer more complete I would suggest you to also mention the java sdk/jvm you used. Since the successful working of this would be based on implementation of java platform you are using. – Gopi Aug 26 '10 at 05:44
  • @Gopi, because of the string "elementData"? I don't think the specific JVM matters, but for reference I used Hotspot and Suns 1.6.0.20 rt.jar. – aioobe Aug 26 '10 at 06:56
  • @aiobee yes because of 'elementData'. I think its quite possible that all implementations of ArrayList may not have this field or this field with same name. – Gopi Aug 26 '10 at 08:01
  • @Gopi. You're absolutely right. Since it is a private variable, nothing in the api specifies the actual name. If it would have had a package, public or protected scope, things would be different :-) – aioobe Aug 26 '10 at 09:00
  • @Gopi, you are right. In Android's ArrayList implementation, the field is "transient Object[] array;" instead of "elementData". So we can use "array" instead. – situee Jun 28 '12 at 08:50
  • I disagree with you. Knowing actual capacity of list is helpful when you decide to trimToSize() such list or not. If capacity is not far greater then size of the list such operation could not be necessary. – Marco Jul 04 '12 at 21:30
  • I use this in a JUnit test to check if the capacity is equal to the size(). This is one undocumented objective of a particular implementation. – T-Bull Jun 15 '13 at 12:08
21

No you cannot ! Java ArrayList do not provide a way to access its current capacity.

You can only construct an ArrayList specifying an initial capacity using constructor ArrayList(int initialCapacity) or increase the capacity by calling ensureCapacity().

Gopi
  • 10,073
  • 4
  • 31
  • 45
10

The ArrayList is an abstraction for an automatically growable List of elements. You rarely need to know its capacity. Consider Effective Java 2nd Edition, Item 52: Refer to objects by their interfaces. As much as practical, you should not even care if it's an ArrayList or a LinkedList; it's just a List.

That said, these methods may be of interest to you:

  • ArrayList(int initialCapacity)
    • Constructs an empty list with the specified initial capacity.
  • void ensureCapacity(int minCapacity)
    • Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
  • void trimToSize()
    • Trims the capacity of this ArrayList instance to be the list's current size. An application can use this operation to minimize the storage of an ArrayList instance.
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
1

From the specification: "The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost."

So there's no way to tell what the current capacity is, nor how it grows.

Jeroen Rosenberg
  • 4,552
  • 3
  • 27
  • 39
1

The API doesn't provide it. Internally, the capacity is multiplied by a factor whenever add(..) is called while in full capacity. However, the Java specification doesn't say anything about this constant factor... Sun's implementation uses a factor of 1.5, so you have an upper bound of 1.5*size() for the capacity.

Remember that you can use trimToSize() to "compact" the list and make the capacity equal to size().

Eyal Schneider
  • 22,166
  • 5
  • 47
  • 78
1

I'm going to buck the trend here...the user has a question albeit with no context. Without context, knowing the capacity is unnecessary as the backing array will grow to accommodate...

You can do the following to know for certain what the capacity is with your ArrayList. The side effect is the backing array will be trimmed to the exact number of elements in the array:

ArrayList list = new ArrayList();
//add a bunch of elements
list.trimToSize();
System.out.println("Capacity = " + list.size());

Enjoy!

Tim Reddy
  • 4,340
  • 1
  • 40
  • 77
  • 3
    In ArrayList the size() method returns how many elements(objects) are there in the list not the capacity. – subhashis Apr 20 '15 at 11:20
0

You don't need to worry about the capacity, that is an internal implementation detail. If the internal array fills, then it will expand. You can find out how many elements are currently in your ArrayList with the size() method.

Noel M
  • 15,812
  • 8
  • 39
  • 47
0

Do you need this at runtime or is it ok to get while performing testing? If its testing you can usually see the capacity using your favourite IDE debugger. I don't have the exact number, but 1.7 is usually the capacity growth size. So if you create an arraylist with 10 items, java will make it size 17.

Steve
  • 21,163
  • 21
  • 69
  • 92