In Java 8, why is the default capacity of ArrayList now zero?

arraylist default size increases in java
default size of array
how to find default size of arraylist in java
default size of hashmap
arraylist default size and load factor
default capacity of vector in java
default size of linkedlist in java
how to set arraylist size in java

As I recall, before Java 8, the default capacity of ArrayList was 10.

Surprisingly, the comment on the default (void) constructor still says: Constructs an empty list with an initial capacity of ten.

From ArrayList.java:

/**
 * Shared empty array instance used for default sized empty instances. We
 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
 * first element is added.
 */
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

...

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

Technically, it's 10, not zero, if you admit for a lazy initialisation of the backing array. See:

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

where

/**
 * Default initial capacity.
 */
private static final int DEFAULT_CAPACITY = 10;

What you're referring to is just the zero-sized initial array object that is shared among all initially empty ArrayList objects. I.e. the capacity of 10 is guaranteed lazily, an optimisation that is present also in Java 7.

Admittedly, the constructor contract is not entirely accurate. Perhaps this is the source of confusion here.

Background

Here's an E-Mail by Mike Duigou

I have posted an updated version of the empty ArrayList and HashMap patch.

http://cr.openjdk.java.net/~mduigou/JDK-7143928/1/webrev/

This revised implementation introduces no new fields to either class. For ArrayList the lazy allocation of the backing array occurs only if the list is created at default size. According to our performance analysis team, approximately 85% of ArrayList instances are created at default size so this optimization will be valid for an overwhelming majority of cases.

For HashMap, creative use is made of the threshold field to track the requested initial size until the bucket array is needed. On the read side the empty map case is tested with isEmpty(). On the write size a comparison of (table == EMPTY_TABLE) is used to detect the need to inflate the bucket array. In readObject there's a little more work to try to choose an efficient initial capacity.

From: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/015585.html

In Java 8, why is the default capacity of ArrayList now zero? : learnjava, In java 8 default capacity of ArrayList is 0 until we add at least one ArrayList al = new ArrayList(); //Size: 0, Capacity: 0 ArrayList al = new  In java 8 default capacity of ArrayList is 0 until we add at least one object into the ArrayList object (You can call it lazy initialization). Please see below code for help. ArrayList al = new ArrayList(); //Size: 0, Capacity: 0 ArrayList al = new ArrayList(5); //Size: 0, Capacity: 5 ArrayList al = new ArrayList(new ArrayList(5)); //Size: 0, Capacity: 0 al.add( "shailesh" ); //Size: 1, Capacity: 10 public static void main( String[] args ) throws Exception { ArrayList al = new ArrayList();

In java 8 default capacity of ArrayList is 0 until we add at least one object into the ArrayList object (You can call it lazy initialization).

Now question is why this change has been done in JAVA 8?

Answer is to save memory consumption. Millions of array list objects are created in real time java applications. Default size of 10 objects means that we allocate 10 pointers (40 or 80 bytes) for underlying array at creation and fill them in with nulls. An empty array (filled with nulls) occupy lot of memory .

Lazy initialization postpones this memory consumption till moment you will actually use the array list.

Please see below code for help.

ArrayList al = new ArrayList();          //Size:  0, Capacity:  0
ArrayList al = new ArrayList(5);         //Size:  0, Capacity:  5
ArrayList al = new ArrayList(new ArrayList(5)); //Size:  0, Capacity:  0
al.add( "shailesh" );                    //Size:  1, Capacity: 10

public static void main( String[] args )
        throws Exception
    {
        ArrayList al = new ArrayList();
        getCapacity( al );
        al.add( "shailesh" );
        getCapacity( al );
    }

    static void getCapacity( ArrayList<?> l )
        throws Exception
    {
        Field dataField = ArrayList.class.getDeclaredField( "elementData" );
        dataField.setAccessible( true );
        System.out.format( "Size: %2d, Capacity: %2d%n", l.size(), ( (Object[]) dataField.get( l ) ).length );
}

Response: - 
Size:  0, Capacity:  0
Size:  1, Capacity: 10

Article Default capacity of ArrayList in Java 8 explains it in details.

In Java 8, why is the default capacity of ArrayList now zero?, it is empty. It is also a dynamic container meaning it will grow so for you to ask if it is "full" is more of a constraint you'd need to add to your code. size () returns the number of items currently in the list, which of course is zero when the list is created. What you're interested in the capacity, the size of the internal array including empty elements. I don't believe ArrayList offers an API that provides this information. [Jess in Action] [AskingGoodQuestions]

If the very first operation that is done with an ArrayList is to pass addAll a collection which has more than ten elements, then any effort put into creating an initial ten-element array to hold the ArrayList's contents would be thrown out the window. Whenever something is added to an ArrayList it's necessary to test whether the size of the resulting list will exceed the size of the backing store; allowing the initial backing store to have size zero rather than ten will cause this test to fail one extra time in the lifetime of a list whose first operation is an "add" which would require creating the initial ten-item array, but that cost is less than the cost of creating a ten-item array that never ends up getting used.

That having been said, it might have been possible to improve performance further in some contexts if there were a overload of "addAll" which specified how many items (if any) would likely be added to the list after the present one, and which could use that to influence its allocation behavior. In some cases code which adds the last few items to a list will have a pretty good idea that the list is never going to need any space beyond that. There are many situations where a list will get populated once and never modified after that. If at the point code knows that the ultimate size of a list will be 170 elements, it has 150 elements and a backing store of size 160, growing the backing store to size 320 will be unhelpful and leaving it at size 320 or trimming it to 170 will be less efficient than simply having the next allocation grow it to 170.

How to find length/size of ArrayList in Java? Example, When you create an object of ArrayList in Java without specifying a capacity, it is method to trim the capacity of this ArrayList instance to be the list's current size. From above example, you can see that initial size of ArrayList was zero,  In java 8 default capacity of ArrayList is 0 until we add at least one object into the ArrayList object (You can call it lazy initialization). Now question is why this change has been done in JAVA 8? Answer is to save memory consumption. Millions of array list objects are created in real time java applications.

The question is 'why?'.

Memory profiling inspections (for example (https://www.yourkit.com/docs/java/help/inspections_mem.jsp#sparse_arrays) shows that empty (filled with nulls) arrays occupy tons of memory .

Default size of 10 objects means that we allocate 10 pointers (40 or 80 bytes) for underlying array at creation and fill them in with nulls. Real java applications create millions of array lists.

The introduced modification removes^W postpone this memory consumption till moment you will actually use the array list.

Java - ArrayList default initial values, Initial default size is 10. Now by giving below statements in actual implementation of arrayList new capacity will be 15. int oldCapacity =  I saw the java doc for ArrayList and found that the initial capacity of ArrayList is 10. /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this(10); } I think it would make sense if it were any power of 2, but why 10? I also checked HashMap's initial capacity, and it's 16 which makes sense.

ArrayList default size in JAVA 8 is stil 10. The only change made in JAVA 8 is that if a coder adds elements less than 10 then the remaining arraylist blank places are not specified to null. Saying so because I have myself gone through this situation and eclipse made me look into this change of JAVA 8.

You can justify this change by looking at below screenshot. In it you can see that ArrayList size is specified as 10 in Object[10] but the number of elements displayed are only 7. Rest null value elements are not displayed here. In JAVA 7 below screenshot is same with just a single change which is that the null value elements are also displayed for which the coder needs to write code for handling null values if he is iterating complete array list while in JAVA 8 this burden is removed from the head of coder/developer.

Screen shot link.

Java.util.Vector Class in Java, Null values are allowed in ArrayList. 8. ArrayList is not synchronized Now if we will try to add 11th element in this array as below When we instantiate an ArrayList,it is instantiated with initial capacity of 10,which means an  Even though we created ArrayList with a capacity of 2, the size remains 0 because we have not added any elements to it. How to check ArrayList capacity? There is no direct way to check ArrayList capacity. The ArrayList class maintains a private Object array named elementData. Though it is never required, you may access this private array’s length to check the capacity of the ArrayList using Java reflection for experimental purposes.

Java ArrayList Index, Constructs an empty list with an initial capacity of ten. ArrayList(Collection<? extends E> c). Constructs a list containing the elements of the specified collection​, in  The array that ArrayList uses has to have a default size, obviously. 10 is probably a more or less arbitrary number for the default number of elements. When you create a new ArrayList with nothing in it, then ArrayList will have made an array of 10 elements behind the scenes. Ofcourse those 10 elements are all null.

Java ArrayList ensureCapacity() method example, Today more than ever, executives are tasked with maintaining their Originally Answered: What is a default size of ArrayList, Vector, HashMap, Hashtable and Hashset? that its internal data array has size 10 and its standard capacity increment is zero. How do you iterate over a Hash map of arraylists of String in Java? 93 In Java 8, why is the default capacity of ArrayList now zero? 67 Why doesn't Java allow to throw a checked exception from static initialization block? 63 Disable XML validation in Eclipse

ArrayList features every Java developer must , If the size of the current elements (including the new element to be added to the As observed, in Java 8 private keyword is removed to provide access to nested When an object of ArrayList is created without initial capacity, the default @​throws NullPointerException if the specified collection is null. */. Because an ArrayList certainly doesn't have a zero initial capacity (it's 10 by default), and it does allow you to set it. If you do, it's not really accurate to say that an ArrayList has a zero capacity increment, rather that it doesn't use the concept at all.

Comments
  • According to bugs.java.com/bugdatabase/view_bug.do?bug_id=7143928 it leads to reduce heap usage and improved response times (the numbers for two appications are shown)
  • @khelwood: ArrayList doesn't really "report" its capacity, other than via this Javadoc: there's no getCapacity() method, or anything like that. (That said, something like ensureCapacity(7) is a no-op for a default-initialized ArrayList, so I guess we really are supposed to act as though its initial capacity were truly 10 . . .)
  • Nice digging. The default initial capacity is indeed not zero, but 10, with the default case being lazily allocated as a special case. You can observe this if you repeatedly add elements to an ArrayList created with the no-arg constructor vs passing zero to the int constructor, and if you look at the internal array size reflectively or in a debugger. In the default case the array jumps from length 0 to 10, then to 15, 22, following the 1.5x growth rate. Passing zero as the initial capacity results in growth from 0 to 1, 2, 3, 4, 6, 9, 13, 19....
  • I am Mike Duigou, author of the change and the quoted email and I approve this message. 🙂 As Stuart says the motivation was primarily about space saving rather than performance though there is also a slight performance benefit due to frequently avoiding creation of the backing array.
  • @assylias: ;^) no, it still has its place as a singleton emptyList() still consumes less memory than several empty ArrayList instances. It’s just less important now and thus not needed at every place, especially not at places with a higher likelihood of adding elements at a later time. Also keep in mind that you sometimes want an immutable empty list and then emptyList() is the way to go.
  • Very good points about addAll(). That is yet another opportunity for improving efficiency around the first malloc.
  • @kevinarpe: I wish Java's library had engineered in some more ways for programs to indicate how things were likely to be used. The old style of substring, for example, was lousy for some uses cases, but excellent for others. Had there been separate functions for "substring which is likely to outlast the original" and "substring which is unlikely to outlast the original", and code used the right one 90% of the time, I would think those could have greatly outperformed either the old or new string implementation.
  • Please correct "consume" with "waste". The link you provide does not imply they start gobbling up memory everywhere, just that arrays with null elements waste the memory that is allocated for them, disproportionately. "Consume" implies they magically use memory beyond their allocation, which is not the case.