How does the size of ArrayList grow dynamically in Java? And also state how it is implemented internally? More details, preferably with source code interpretation
In Java, an ArrayList
is a resizable array implementation of the List
interface. It can grow dynamically as elements are added to it. The internal mechanism of how an ArrayList
grows involves a few key concepts, including an underlying array, a size counter, and a resizing strategy.
Underlying Array:
ArrayList
uses an array to store its elements. When you create an ArrayList
, it initializes an array of a certain capacity (default is 10).Size Counter:
Dynamic Resizing:
ArrayList
and the current size equals the capacity of the underlying array, the ArrayList
needs to grow. This is done by creating a new array with a larger capacity (usually 1.5 to 2 times the current capacity), copying the elements from the old array to the new array, and then adding the new element.Here’s a simplified version of how the ArrayList
might be implemented internally:
import java.util.Arrays;
public class MyArrayList<E> {
private Object[] elementData; // Array to store elements
private int size; // Current number of elements
// Default constructor
public MyArrayList() {
this.elementData = new Object[10]; // Initial capacity
this.size = 0;
}
// Method to add an element
public void add(E element) {
ensureCapacity(size + 1); // Ensure there's enough space
elementData[size++] = element; // Add element and increment size
}
// Method to ensure capacity
private void ensureCapacity(int minCapacity) {
if (minCapacity - elementData.length > 0) {
// Calculate new capacity (1.5 times the current capacity)
int newCapacity = elementData.length + (elementData.length >> 1);
// If new capacity is less than minCapacity, use minCapacity
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
// Resize the array
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
// Method to get an element
public E get(int index) {
if (index >= size || index < 0) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
return (E) elementData[index];
}
// Method to get the current size
public int size() {
return size;
}
}
Array Initialization:
elementData
array is initialized with a default capacity of 10.Adding Elements:
add
method first calls ensureCapacity
to check if there is enough space to add a new element. If not, it resizes the array.Ensuring Capacity:
ensureCapacity
method checks if the current array can accommodate the new element. If not, it calculates a new capacity (1.5 times the current capacity) and uses Arrays.copyOf
to create a new array and copy the existing elements into it.Getting Elements:
get
method retrieves an element at a specified index, checking for bounds to avoid IndexOutOfBoundsException
.Size Method:
size
method returns the current number of elements in the ArrayList
.add
operation has an amortized time complexity of O(1). Although resizing the array takes O(n) time, it happens infrequently, so the average time per addition remains constant.ArrayList
may use more memory than necessary due to the resizing strategy, especially if many elements are added and removed.The dynamic resizing of ArrayList
in Java is a powerful feature that allows for flexible data storage. Understanding its internal workings can help developers make informed decisions about when to use ArrayList
and how to manage performance in applications.