ArrayList
About
ArrayList is a part of the Java Collections Framework and resides in the java.util package. It is a resizable array implementation of the List interface and provides dynamic array capabilities. Unlike standard arrays, ArrayList can grow and shrink dynamically, making it more flexible when dealing with an unknown number of elements.
Features of ArrayList
Dynamic Resizing: Automatically resizes as elements are added or removed.
Random Access: Allows retrieving elements in constant time, O(1), using indices.
Duplicates Allowed: Allows duplicate elements, unlike
Set.Maintains Insertion Order: Elements are stored in the order they are inserted.
Generic Support: Enables type safety, preventing runtime
ClassCastException.ArrayList<String> names = new ArrayList<>();Custom Capacity Management: Initial capacity can be set to avoid frequent resizing.
ArrayList<Integer> numbers = new ArrayList<>(100);Serialization Support: Implements
Serializable, making it suitable for object serialization.Iterator and ListIterator Support: Traversing the list in both forward and backward directions.
Fail-Fast Behavior: Throws
ConcurrentModificationExceptionif the list is structurally modified while iterating.
Key Methods
add(E e): Adds an element.get(int index): Retrieves an element by index.set(int index, E element): Replaces the element at a specified position.remove(int index)/remove(Object o): Removes an element.size(): Returns the number of elements.isEmpty(): Checks if the list is empty.contains(Object o): Checks if the list contains a specified element.clear(): Removes all elements.addAll(Collection<? extends E> c): Adds all elements of a collection.retainAll(Collection<?> c): Retains only elements present in the specified collection.subList(int fromIndex, int toIndex): Returns a portion of the list.toArray(): Converts the list into an array.
Big(O) for Operations on ArrayList
The performance of ArrayList operations depends on the dynamic resizing of the internal array and how elements are accessed or modified. Below is the time complexity for various operations:
Operation
Big(O) Time Complexity
Details
Access by Index
O(1)
Direct indexing makes retrieval constant time.
Add (at end)
O(1) Amortized
Appending is constant unless resizing occurs (then O(n) for resizing).
Add (at specific index)
O(n)
Shifts elements after the index to the right.
Remove (by index)
O(n)
Shifts elements after the removed index to the left.
Remove (by value)
O(n)
Searches for the value first (O(n)) and then removes it.
Search (by value)
O(n)
Iterates through the array to find the value.
Contains
O(n)
Iterates through the array to check if the value exists.
Iteration (using for-loop)
O(n)
Iterates through each element once.
Dynamic Resizing (growth)
O(n) Rarely occurs
Copies all elements to a new larger array when resizing.
Examples
Basic Operation
Generic ArrayLists
Type Safety:
The
ArrayListis declared with the generic type<Integer>.This ensures that only
Integerobjects can be added tointList, avoiding runtimeClassCastException.Generics enforce compile-time type checking.
Stream API Compatibility:
The
intList.stream()method returns aStream<Integer>because the list is generic withIntegertype.The stream operation
.mapToInt(Integer::intValue)converts theStream<Integer>into anIntStreamfor summation.This operation is efficient because it avoids boxing/unboxing operations during summation.
Eliminating Casting:
Without generics, we would need to cast objects manually when retrieving elements, which is error-prone:
Custom Sorting with Comparators
Using Streams
Last updated