Mechanics of Element Removal in Java ArrayList

Deletion in ArrayList relies on shifting underlying array elements and does not trigger capacity reduction. The internal array maintains its length; only the logical size decreases.

Index-Based Deletion

When removing an element by its position, the underlying array must shift subsequent elements to fill the gap.

public T removeByPosition(int pos) {
    verifyBounds(pos);

    structuralChanges++;
    T removedVal = fetchFromInternalArray(pos);

    int shiftCount = currentElementCount - pos - 1;
    if (shiftCount > 0) {
        System.arraycopy(internalArray, pos + 1, internalArray, pos, shiftCount);
    }
    internalArray[--currentElementCount] = null; // Nullify for GC

    return removedVal;
}
  • Bound Verification: The method first confirms the position is valid. If the position equals or exceeds the logical size, an IndexOutOfBoundsException is thrown.
  • Structural Modification Counter: The structuralChanges counter increments to support fail-fast iteration, preventing concurrent modification issues.
  • Value Extraction: The target element is retrieved from the backing array to be returned to the caller.
  • Shift Calculation: It determines how many items must move left by calculating currentElementCount - pos - 1.
  • Array Copying: If elements exist after the target position, System.arraycopy shifts them leftward, overwriting the deleted slot.
  • Garbage Collection Assistance: The now-unused last slot is nulled out, and the logical element count is decremented, allowing the garbage collector to reclaim the orphaned object.

Object-Based Deletion

Removing a specific object requires locating its first occurrence before deletion.

public boolean deleteByValue(Object target) {
    if (target == null) {
        for (int i = 0; i < currentElementCount; i++) {
            if (internalArray[i] == null) {
                internalDelete(i);
                return true;
            }
        }
    } else {
        for (int i = 0; i < currentElementCount; i++) {
            if (target.equals(internalArray[i])) {
                internalDelete(i);
                return true;
            }
        }
    }
    return false;
}
  • Null Handling: If the target is null, the loop searches for the first null reference in the array.
  • Equality Check: For non-null targets, the loop relies on the equals method to find a match.
  • Execution: Upon finding the match, the private internalDelete method processes the actual removal, and the method returns true. If no match is found, it returns false.

Internal Deletion Helper

The object-based removal delegates to an optimized helper that skips bound checks and return value extraction.

private void internalDelete(int pos) {
    structuralChanges++;
    int shiftCount = currentElementCount - pos - 1;
    if (shiftCount > 0) {
        System.arraycopy(internalArray, pos + 1, internalArray, pos, shiftCount);
    }
    internalArray[--currentElementCount] = null;
}

This helper mirrors the index-based deletion logic—incrementing the modification counter, shifting elements left via System.arraycopy, and nullifying the trailing slot to aid garbage collection—while omitting the boundary check and value retrieval steps.

Tags: java ArrayList source code Data Structures

Posted on Mon, 18 May 2026 13:00:10 +0000 by Krik