Java Programming Handbook

    Java ArrayList

    The ArrayList class in Java is a part of the Java Collection Framework and provides a resizable-array implementation of the List interface. It is widely used due to its simplicity, performance, and flexibility in handling dynamic data.

    1. What is an ArrayList?#

    • ArrayList is a dynamic array, which means it grows or shrinks as elements are added or removed.
    • Unlike arrays, we don’t need to specify the size while creating an ArrayList.
    List<String> list = new ArrayList<>();

    2. Internal Working#

    • Internally uses an array to store elements.
    • When the array gets full, it creates a new array with a larger capacity (usually 1.5x the old size) and copies the old elements to it.

    3. Constructors#

    ArrayList() // Default constructor with initial capacity 10 ArrayList(int initialCapacity) // Initializes with specified capacity ArrayList(Collection<? extends E> c) // Initializes with elements of another collection

    4. Commonly Used Methods with Examples#

    1. add(E e) – Adds element to the end#

    ArrayList<String> list = new ArrayList<>(); list.add("Apple"); System.out.println(list);

    Output:

    [Apple]

    2. add(int index, E element) – Inserts at specific index#

    list.add(0, "Banana"); System.out.println(list);

    Output:

    [Banana, Apple]

    3. get(int index) – Retrieves element at index#

    String item = list.get(1); System.out.println(item);

    Output:

    Apple

    4. set(int index, E element) – Replaces element at index#

    list.set(1, "Orange"); System.out.println(list);

    Output:

    [Banana, Orange]

    5. remove(int index) – Removes element at index#

    list.remove(0); System.out.println(list);

    Output:

    [Orange]

    6. remove(Object o) – Removes first occurrence of element#

    list.remove("Orange"); System.out.println(list);

    Output:

    []

    7. size() – Returns number of elements#

    System.out.println(list.size());

    Output:

    0

    8. isEmpty() – Checks if list is empty#

    System.out.println(list.isEmpty());

    Output:

    true

    9. contains(Object o) – Checks if element exists#

    list.add("Mango"); System.out.println(list.contains("Mango"));

    Output:

    true

    10. indexOf(Object o) – Returns first index of element#

    list.add("Banana"); System.out.println(list.indexOf("Banana"));

    Output:

    1

    11. lastIndexOf(Object o) – Returns last index of element#

    list.add("Mango"); System.out.println(list.lastIndexOf("Mango"));

    Output:

    2

    12. clear() – Removes all elements#

    list.clear(); System.out.println(list);

    Output:

    []

    13. toArray() – Converts list to array#

    ArrayList<String> fruits = new ArrayList<>(); fruits.add("Apple"); fruits.add("Banana"); String[] array = fruits.toArray(new String[0]); System.out.println(Arrays.toString(array));

    Output:

    [Apple, Banana]

    14. ensureCapacity(int minCapacity) – Increases internal capacity#

    ArrayList<Integer> nums = new ArrayList<>(); nums.ensureCapacity(100); // ensures internal capacity >= 100

    (No visible output but improves performance if adding many elements.)

    15. trimToSize() – Trims capacity to current size#

    nums.trimToSize(); // trims to current size

    (No visible output, but optimizes memory usage.)

    16. forEach(Consumer<? super E> action) – Lambda-style iteration#

    fruits.forEach(fruit -> System.out.println("Fruit: " + fruit));

    Output:

    Fruit: Apple Fruit: Banana

    5. Performance#

    OperationTime Complexity
    Access (get/set)O(1)
    Add/remove at endO(1) amortized
    Add/remove middleO(n)

    6. Thread Safety#

    • ArrayList is not synchronized.
    • For thread-safe operations, use:
    List<String> syncList = Collections.synchronizedList(new ArrayList<>());

    7. When to Use ArrayList?#

    • When you need fast access and iteration.
    • When insertion/deletion in the middle is rare.
    • When working in a single-threaded or externally synchronized environment.

    8. Best Practices#

    • Prefer List interface while declaring:
    List<String> names = new ArrayList<>();
    • Use initialCapacity if size is known beforehand.
    • Avoid using ArrayList in multi-threaded scenarios unless synchronized.

    Conclusion#

    ArrayList is a powerful and flexible implementation of the List interface. It is ideal for most general-purpose use cases where fast access and iteration are required. Understanding its methods and behavior can help you make efficient decisions in your Java programs.

    In the next blog, we’ll dive deep into LinkedList – its internal structure, performance implications, and ideal use cases!

    Last updated on Apr 09, 2025