I was going through the source code of ArrayList. I came across the method ensureCapacity() which increases the capacity of the data array used internally. In that, the new capacity of the data array was increased based on logic int newCapacity = (oldCapacity * 3)/2 + 1;
where old capacity is the current data array size. Is there any particular reason for choosing (oldCapacity * 3)/2 + 1
this as new array size, if so what is it?
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
Thanks in advance ...
The only guarantee made in the JavaDoc is that adding a new element has constant amortized time. That means that the average time of adding a new element to the array is constant. Sometimes it might take a bit longer (like when trying to resize the array), but overall these cases are rare enough for it not to affect the average too much.
So for them to be able to respect that guarantee they need to make sure the resizing happens rarely enough as to not affect the average adding time. They use a percent of the current capacity for the new capacity for this reason. If the resize would be something like oldCapacity + 50
the array would be too big for small arrayLists, but if you want to add a few thousand elements, resizing every 50 elements would bring the performance way down. This way the capacity increases exponentially (if you already added a lot of elements, chances are you will add more, so they increase the capacity by more) so it doesn't degrade the performance too much.
As to why they chose 50%, perhaps they felt that doubling (or more) the capacity might be overkill (would consume too much extra memory for very large ArrayLists), and going too low (like perhaps 10-25%) would degrade the performance too much (by doing too many reallocations), so probably +50% offered good enough performance, without taking too much extra memory. I'm guessing they did some performance tests before deciding on the value.
It grows the list by 50% every time it is called, to prevent allocating the world too soon. The + 1
is meant to catch situations where the list was inititalised with a size of 1 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With