Dedyshka
Dedyshka

Reputation: 471

Default size of ArrayList

Looking through some piece of code I noticed one strange initialization of ArrayList:

... = new ArrayList<..>(0);

I've opened JavaSE 7 sources and saw that inner elementData arrray is initialized by empty array constant - {}. When we pass capacity to the ArrayList constructor we do almost the same - new Object[0]. So my question is: is there is any difference between new ArrayList(0) and new ArrayList() ? Shouldn't ArrayList set the default capacity size to smth like 10 ?

Thanks all for answers.

Upvotes: 6

Views: 17409

Answers (4)

Jesus Zavarce
Jesus Zavarce

Reputation: 1759

It is necessary to clarify two definitions:

The size represent the number of elements in the list.

The capacity represent the length of the internal array. In other words, the length contains the number of places to put an element;

Exemple of the length of an array list size = 2

When you create one list with the default constructor of Arraylist:

Ex:

List<String> list = new ArrayList<>();
System.out.println(l.size());

The output is : 0

Why?

Because the list is empty, this is explained by the internal array of the list, when you use the default constructor of ArrayList, the internal array is :

private static final Object[] EMPTY_ELEMENTDATA = {}; 

So, an empty array of Objects where the value of the length is 0 (Capacity). As the list is empty the size is 0.

state of the list when the default constructor is used (id of elementData=27)

When you add one element to the list, the size of your list is incremented to 1, and the initial internal array of your list is changed by another array with a length of 10 (capacity); (id of elementData=30)

private static final int DEFAULT_CAPACITY = 10

State of the list after add one element (id of elementData=30)

About the default constructor of ArrayList, the API java says : API Java : https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList%28%29

public ArrayList()

Constructs an empty list with an initial capacity of ten.

In other words, this constructor create an empty list (size equals to 0) with an initial capacity of ten elements.(After add one element to the list, the capacity of the list become 10)

When you know the size of your list, you should create your list with this size. Why? because the complexity of the method add (E element) is O(1) amortized (when there is available space in your list), but O(n) (worst-case) if you add more elements than the initial capacity of your list, in this case, a new array (1.5 times the size) is allocated, and the old array is copied to the new one. Clearly, this operation has costs in terms of performance and memory resources.

So, create a list with an initial capacity of 0 has no sense. If you don't know the initial capacity of your list, use the default constructor that give to you one list with an initial capacity of ten elements.

Keep in mind that definitions of size and capacity around ArrayList are differents:

From book Core Java 2: Fundamentals

Allocating an array list as new ArrayList <'Employee>(100) // capacity is 100

is not the same as allocating a new array as new Employee[100] // size is 100

There is an important distinction between the capacity of an array list and the size of an array. If you allocate an array with 100 entries, then the array has 100 slots, ready for use. An array list with a capacity of 100 elements has the potential of holding 100 elements (and, in fact, more than 100, at the cost of additional reallocations); but at the beginning, even after its initial construction, an array list holds no elements at all.

Upvotes: 7

Ruslanas
Ruslanas

Reputation: 61

ArrayList() will make list capacity of 10 (default) after first element added. However ArrayList(0) will keep capacity small - it will be 1 after first element added, 2 after the second add, and etc.

Upvotes: 1

wero
wero

Reputation: 33000

An ArrayList has an internal array to store the list elements.

There is a difference between the two constructor calls in Java 7 and 8:

If you do new ArrayList<>(0) the ArrayList creates a new Object array of size 0.

If you do new ArrayList<>() the ArrayList uses a static empty Object array of size 0 and switches to an own private array once you add items to the list.

EDIT:

The Javadoc of the default ArrayList constructor seems to contradict this.

/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
    super();
    this.elementData = EMPTY_DEFAULTCAPACITY_EMPTY_ELEMENTDATA; // = static, empty
}

But it does not create an element array of length 10 immediately, but instead when you add elements or ensure the capacity:

public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        // any size if not default element table
        ? 0
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        : DEFAULT_CAPACITY; // = 10

    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}

Upvotes: 4

Gavriel
Gavriel

Reputation: 19237

ArrayList has 2 constructors. The default constructor just calls the other one with capacity=10:

ArrayList() {this(10);}

ArrayList(capacity)

What capacity means? It means that an array of the size capacity is allocated to hold the items in the arraylist. Whenever it's too small to hold the necessary items, it's being resized, by creating a bigger array and copying everything over (takes time) + it means the old array needs to be garbage collected (even more time). That's why it is important to get the correct capacity right. Although it will work with any initial capacity, it can be slow. On the other hand having huge capacity and almost no items in it is wasting memory.

Note: Arraylist(0) will create a 0 size array, and when you try to add the 1st element, it'll be thrown away and a new array allocated.

Upvotes: 1

Related Questions