Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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; } 
like image 621
kevinarpe Avatar asked Dec 13 '15 10:12

kevinarpe


People also ask

What is the default capacity of ArrayList in Java?

Whenever an instance of ArrayList in Java is created then by default the capacity of Arraylist is 10. Since ArrayList is a growable array, it automatically resizes itself whenever a number of elements in ArrayList grow beyond a threshold. However, ensureCapacity() method of java.

Does an ArrayList have a default size?

The default size of ArrayList in java is 10. But an ArrayList is a growable array, unlike array it doesn't have a fixed length. It increases the size dynamically whenever we add or remove any element in ArrayList. We can initialize the capacity of ArrayList during the creation of ArrayList.

Does an ArrayList start at 0 in Java?

Exactly as arrays in all C-like languages. The indexes start from 0.

Can an ArrayList have a size of 0?

Another way to check if arraylist contains any element or not, we can check the size of arraylist. If the list size is greater than zero, then list is not empty. If list size is 0, list is empty.


2 Answers

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

like image 50
Lukas Eder Avatar answered Sep 19 '22 15:09

Lukas Eder


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.

like image 44
Shailesh Vikram Singh Avatar answered Sep 18 '22 15:09

Shailesh Vikram Singh