The AbstractList Class and ArrayList Class in Java Collection

 Introduction

The AbstractList class in the Java Collections Framework provides a skeletal implementation of the List interface, enabling developers to create custom list implementations with ease. It offers default implementations for some list operations, allowing focus on specific aspects of the custom list. On the other hand, the ArrayList class is a concrete implementation of the List interface that uses a dynamic array to store elements. Known for its resizable nature and efficient index-based access, ArrayList is ideal for scenarios requiring frequent access and modification of elements. While AbstractList serves as a base for custom list creation, ArrayList provides a versatile and practical solution for dynamic list management.

The AbstractList Class

The AbstractList class extends the AbstractCollection class and implements the List interface, allowing for random access to data. For example, it enables the use of index values to access elements in an array at random. The constructor for this class is represented as: protected AbstractList(). The AbstractList class extends methods such as add(Object o), clear(), and iterator() from the AbstractCollection class, and it also inherits methods from the List interface.

Source Code

import java.util.AbstractList;

public class SimpleList<E> extends AbstractList<E> {
    private Object[] elements;
    private int size;

    public SimpleList(int capacity) {
        elements = new Object[capacity];
        size = 0;
    }
    @Override
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        return (E) elements[index];
    }
    @Override
    public int size() {
        return size;
    }
    @Override
    public boolean add(E e) {
        if (size == elements.length) {
            ensureCapacity(size + 1);
        }
        elements[size++] = e;
        return true;
    }
    private void ensureCapacity(int minCapacity) {
        int oldCapacity = elements.length;
        if (minCapacity > oldCapacity) {
            int newCapacity = oldCapacity * 2;
            if (newCapacity < minCapacity) {
                newCapacity = minCapacity;
            }
            Object[] newElements = new Object[newCapacity];
            System.arraycopy(elements, 0, newElements, 0, size);
            elements = newElements;
        }
    }
    public static void main(String[] args) {
        SimpleList<String> myList = new SimpleList<>(5);
        myList.add("Apple");
        myList.add("Banana");
        myList.add("Cherry");
        for (int i = 0; i < myList.size(); i++) {
            System.out.println(myList.get(i));
        }
    }
}

Output

Command Prompt

The provided code defines a custom list implementation named SimpleList by extending the AbstractList class in Java. The SimpleList class uses an internal array to store elements and supports dynamic resizing. It includes a constructor that initializes the list with a specified capacity and methods to add elements (add(E e)), retrieve elements by index (get(int index)), and determine the size of the list (size()). The ensureCapacity(int minCapacity) method is used to resize the internal array when needed. The main method demonstrates the usage of SimpleList by creating an instance, adding a few string elements, and printing them. This example highlights how to build a basic, dynamically resizable list using the AbstractList class.

The ArrayList Class

The ArrayList class extends the AbstractList class and implements the List, Cloneable, and Serializable interfaces. It provides a dynamic array in Java applications, meaning the size of the array is not fixed and can be adjusted at runtime. As elements are added to the ArrayList, its capacity automatically increases to accommodate new elements. Each instance of the ArrayList can store a collection of elements, offering a flexible and resizable solution for managing lists in Java.

Constructor

  • ArrayList(): Create an empty list. The capacity of the list is initialized to ten.
  • ArrayList(Collection c): Creates a list to which the elements of the specified collection are added.
  • ArrayList(int capacity): Creates an empty list. The capacity of the list is initialized to the specified value.

The ArrayList class inherits methods from the List interface, allowing direct access to elements via the get() and set() methods. To add an element to the list, the add() method is used, while the remove() method facilitates the removal of elements from the list.

The below source code illustrates the usage of the add() and remove() methods of the ArrayList class.

import java.util.*;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList<String> arraylist = new ArrayList<>();    
        System.out.println("Initial size of the array list: " + arraylist.size());       
        arraylist.add("A");
        arraylist.add("B");
        arraylist.add("C");
        arraylist.add("D");       
        System.out.println("Size of arraylist after adding elements: " + arraylist.size());
        System.out.println("Contents of arrayList: " + arraylist);      
        arraylist.add(2, "E");    
        System.out.println("Changed contents of arraylist by adding element at the given index: " + arraylist);    
        arraylist.remove(3);
        arraylist.remove("A");      
        System.out.println("Changed contents of arraylist by removing elements from the list: " + arraylist);
    }
}

Output

Output

The provided code demonstrates basic operations on an ArrayList in Java. The ArrayListExample class creates an instance of ArrayList, initially printing its size, which is zero. It then adds four elements ("A", "B", "C", "D") and displays the updated size and contents of the list. The code inserts the element "E" at index 2 and shows the modified list. Subsequently, it removes the element at index 3 and the element "A" by value, printing the final state of the ArrayList. This example illustrates how to manipulate an ArrayList by adding and removing elements and observing the changes in the list's size and contents.

Summary

The AbstractList class in Java provides a skeletal implementation of the List interface, simplifying the creation of custom list implementations by offering default implementations for many methods. It serves as a foundational class that allows developers to focus on the specifics of their custom list while inheriting basic functionality such as element access and size management. In contrast, the ArrayList class is a concrete implementation of the List interface that uses a dynamic array to store elements. It offers efficient index-based access and automatically resizes as elements are added or removed. ArrayList provides a practical and versatile solution for managing lists where frequent access and modification are required. While AbstractList is used as a base for creating specialized lists, ArrayList is a ready-to-use implementation ideal for most dynamic list needs.