I seem to stumble across something interesting in ArrayList
implementation that I can\'t wrap my head around. Here is some code that shows what I mean:
You get precisely what you asked for, respective what has been specified, even in older versions, where the implementation was different:
ArrayList()ArrayList(int)Constructs an empty list with an initial capacity of ten.
Constructs an empty list with the specified initial capacity.
So, constructing the ArrayList
with the default constructor will give you an ArrayList
with an initial capacity of ten, so as long as the list size is ten or smaller, no resize operation will ever be needed.
In contrast, the constructor with the int
argument will precisely use the specified capacity, subject to the growing policy which is specified as
The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.
which applies even when you specify an initial capacity of zero.
Java 8 added the optimization that the creation of the ten elements array is postponed until the first element is added. This is specifically addressing the common case that ArrayList
instances (created with the default capacity) stay empty for a long time or even their entire lifetime. Further, when the first actual operation is addAll
, it might skip the first array resize operation. This does not affect lists with an explicit initial capacity, as those are usually chosen carefully.
As stated in this answer:
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.
The motivation was to optimize precisely these scenarios, not to touch the specified default capacity, which was defined back when ArrayList
was created. (Though JDK 1.4 is the first one specifying it explicitly)