Java Implementation Classes of List

In Java, the List interface is part of the java.util package and provides an ordered collection that allows duplicate elements. To use a List, you must instantiate one of its implementation classes. Below are the most commonly used implementation classes of the List interface, along with their characteristics and use cases.

ArrayList

ArrayList is a resizable array implementation of the List interface. It is the most commonly used implementation due to its fast random access and efficient performance for most use cases.

Characteristics:

  • Fast random access: Provides constant-time performance for retrieving elements by index.

  • Dynamic resizing: Automatically grows when the capacity is exceeded.

  • Efficient for sequential access: Best suited for scenarios where elements are added at the end or accessed frequently by index.

Example:

import java.util.ArrayList;
import java.util.List;

public class Example {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.add("C++");
        System.out.println("ArrayList: " + list);
    }
}

コピー

Use Case:

Use ArrayList when you need fast access to elements and perform minimal insertions or deletions in the middle of the list.

LinkedList

LinkedList is a doubly-linked list implementation of the List interface. It is efficient for frequent insertions and deletions.

Characteristics:

  • Efficient insertions/deletions: Performs well when adding or removing elements at the beginning or middle of the list.

  • Sequential access: Slower than ArrayList for random access due to linear time complexity.

  • Implements Queue and Deque: Can be used as a stack, queue, or deque.

Example:

import java.util.LinkedList;
import java.util.List;

public class Example {
    public static void main(String[] args) {
        List<String> list = new LinkedList<>();
        list.add("Java");
        list.add("Python");
        list.addFirst("C++");
        System.out.println("LinkedList: " + list);
    }
}

コピー

Use Case:

Use LinkedList when you need frequent insertions or deletions, especially at the beginning or middle of the list.

Vector

Vector is a synchronized implementation of the List interface. It is thread-safe but generally slower than ArrayList.

Characteristics:

  • Thread-safe: All methods are synchronized, making it suitable for multi-threaded environments.

  • Legacy class: Introduced in earlier versions of Java, but less commonly used now.

Example:

import java.util.Vector;

public class Example {
    public static void main(String[] args) {
        Vector<String> vector = new Vector<>();
        vector.add("Java");
        vector.add("Python");
        System.out.println("Vector: " + vector);
    }
}

コピー

Use Case:

Use Vector when thread safety is required, but consider alternatives like CopyOnWriteArrayList for better performance.

Stack

Stack is a subclass of Vector that implements a last-in-first-out (LIFO) stack.

Characteristics:

  • LIFO operations: Provides methods like push, pop, and peek.

  • Thread-safe: Inherits synchronization from Vector.

Example:

import java.util.Stack;

public class Example {
    public static void main(String[] args) {
    Stack<String> stack = new Stack<>();
    stack.push("Java");
    stack.push("Python");
    System.out.println("Stack: " + stack);
    System.out.println("Popped: " + stack.pop());
    }
}

コピー

Use Case:

Use Stack for LIFO operations, but consider Deque for better performance and flexibility.

CopyOnWriteArrayList

CopyOnWriteArrayList is a thread-safe implementation of the List interface backed by a copy-on-write array.

Characteristics:

  • Thread-safe: No synchronization is required during iteration.

  • Immutable during iteration: Modifications create a new copy of the array.

  • Best for read-heavy operations: Suitable for scenarios where reads are frequent and writes are rare.

Example:

import java.util.concurrent.CopyOnWriteArrayList;

public class Example {
    public static void main(String[] args) {
    CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
    list.add("Java");
    list.add("Python");
    System.out.println("CopyOnWriteArrayList: " + list);
    }
}

コピー

Use Case:

Use CopyOnWriteArrayList for thread-safe, read-heavy operations where iteration is frequent.

Key Considerations:

  • Use ArrayList for general-purpose, fast access scenarios.

  • Use LinkedList for frequent insertions or deletions.

  • Use Vector or CopyOnWriteArrayList for thread-safe operations.

  • Use Stack for LIFO operations.

Each implementation has its strengths and weaknesses, so choose based on your application's specific requirements.

← Back to Learning Journey