What is the difference between ArrayList and LinkedList in Java?

Java Collections

1. Short Answer

ArrayList and LinkedList are both implementations of the List interface in Java, but they differ in their internal data structures and performance characteristics:

  • ArrayList: Uses a dynamic array internally, providing fast random access but slower insertions/deletions in the middle.
  • LinkedList: Uses a doubly-linked list internally, providing fast insertions/deletions but slower random access.

2. Internal Implementation

Understanding how ArrayList and LinkedList work internally is crucial for making the right choice in your applications.

2.1 ArrayList Implementation

ArrayList is implemented as a dynamic array that grows automatically when needed. Here's a detailed look at its internal workings:

// Simplified ArrayList structure
public class ArrayList {
    private static final int DEFAULT_CAPACITY = 10;
    private Object[] elementData;
    private int size;
    
    // Constructor
    public ArrayList() {
        this.elementData = new Object[DEFAULT_CAPACITY];
    }
    
    // Add method
    public boolean add(E e) {
        ensureCapacity(size + 1);
        elementData[size++] = e;
        return true;
    }
    
    // Get method
    public E get(int index) {
        rangeCheck(index);
        return (E) elementData[index];
    }
}

Key aspects of ArrayList's implementation:

  • Dynamic Array: Uses a regular array that automatically resizes when needed
  • Capacity Management: Starts with default capacity (10) and grows by 50% when full
  • Memory Layout: Elements are stored in contiguous memory locations
  • Resizing Strategy: Creates new array and copies elements when capacity is exceeded
Note

The actual ArrayList implementation in Java is more complex, including optimizations for concurrent access and memory management.

2.2 LinkedList Implementation

LinkedList is implemented as a doubly-linked list, where each element is stored in a node that contains references to both the next and previous nodes:

// Simplified LinkedList structure
public class LinkedList {
    private static class Node {
        E item;
        Node next;
        Node prev;
        
        Node(Node prev, E element, Node next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    
    private Node first;
    private Node last;
    private int size;
    
    // Add method
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    
    // Get method
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
}

Key aspects of LinkedList's implementation:

  • Node Structure: Each element is stored in a node containing the element and references to adjacent nodes
  • Memory Layout: Elements are stored in non-contiguous memory locations
  • Traversal: Requires sequential access through node references
  • Memory Overhead: Each element requires additional memory for node references
Implementation Insight

The doubly-linked structure of LinkedList allows for efficient traversal in both directions and makes operations like adding/removing elements at both ends very fast.

2.3 Memory Management

Both implementations handle memory differently:

  • ArrayList:
    • Uses a single array to store elements
    • May have unused capacity (memory overhead)
    • Requires contiguous memory allocation
    • Memory is allocated in chunks during resizing
  • LinkedList:
    • Allocates memory for each element individually
    • No unused capacity (memory efficient for small lists)
    • Memory can be fragmented
    • Each element requires additional memory for node references

3. Performance Comparison

Let's compare the performance of common operations:

Operation ArrayList LinkedList
Random Access (get) O(1) O(n)
Add at End O(1) amortized O(1)
Add at Start O(n) O(1)
Add in Middle O(n) O(n)
Remove from End O(1) O(1)
Remove from Start O(n) O(1)
Remove from Middle O(n) O(n)
Important

While the time complexity might be the same for some operations, the actual performance can differ significantly due to memory access patterns and CPU cache utilization.

4. Memory Usage

Memory consumption varies between ArrayList and LinkedList:

4.1 ArrayList Memory Usage

  • Stores elements in a single array
  • May have unused capacity (memory overhead)
  • Memory efficient for large lists
  • Better cache locality

4.2 LinkedList Memory Usage

  • Each element requires a node object
  • Additional memory for next/prev references
  • Memory efficient for small lists
  • Poor cache locality
// Memory usage example
List arrayList = new ArrayList<>(1000);  // Pre-allocated array
List linkedList = new LinkedList<>();     // Empty list

// Adding elements
for (int i = 0; i < 1000; i++) {
    arrayList.add(i);   // Uses existing array
    linkedList.add(i);  // Creates new nodes
}

5. Use Cases

Choose the right implementation based on your requirements:

5.1 When to Use ArrayList

  • Frequent random access to elements
  • Mostly adding/removing at the end
  • Large lists with known maximum size
  • Memory efficiency is important
  • Better cache performance needed

5.2 When to Use LinkedList

  • Frequent insertions/deletions at the start
  • Implementing stacks or queues
  • Small to medium-sized lists
  • Memory fragmentation is not a concern
  • Sequential access is the primary operation
Pro Tip

For most use cases, ArrayList is the better choice due to its better memory efficiency and cache performance. Only use LinkedList when you specifically need its unique characteristics.

6. Code Examples

Let's look at some practical examples:

6.1 ArrayList Example

// ArrayList operations
List arrayList = new ArrayList<>();

// Adding elements
arrayList.add("First");
arrayList.add("Second");
arrayList.add(1, "Middle");  // Insert at specific position

// Random access
String element = arrayList.get(1);  // Fast O(1)

// Iteration
for (String item : arrayList) {
    System.out.println(item);
}

// Bulk operations
arrayList.addAll(Arrays.asList("Third", "Fourth"));
arrayList.removeAll(Arrays.asList("First", "Second"));

6.2 LinkedList Example

// LinkedList operations
List linkedList = new LinkedList<>();

// Adding elements
linkedList.addFirst("First");  // Fast O(1)
linkedList.addLast("Last");    // Fast O(1)
linkedList.add(1, "Middle");   // Slower O(n)

// Queue operations
linkedList.offer("New");       // Add to end
String first = linkedList.poll();  // Remove from start

// Stack operations
linkedList.push("Top");        // Add to start
String top = linkedList.pop(); // Remove from start

7. Best Practices

Follow these best practices when working with ArrayList and LinkedList:

7.1 General Guidelines

  • Use ArrayList by default unless you need LinkedList's specific features
  • Pre-allocate ArrayList capacity when possible
  • Avoid frequent insertions/deletions in the middle of ArrayList
  • Use LinkedList for implementing queues or stacks
  • Consider using ArrayDeque instead of LinkedList for queue operations

7.2 Performance Optimization

// Good practice: Pre-allocate ArrayList
List list = new ArrayList<>(1000);  // Specify initial capacity

// Good practice: Use bulk operations
list.addAll(anotherList);  // More efficient than individual adds

// Good practice: Use iterator for LinkedList
Iterator it = linkedList.iterator();
while (it.hasNext()) {
    String item = it.next();
    // Process item
}

// Bad practice: Random access in LinkedList
for (int i = 0; i < linkedList.size(); i++) {
    String item = linkedList.get(i);  // Very slow!
}

8. Conclusion

Understanding the differences between ArrayList and LinkedList is crucial for writing efficient Java code.

Key takeaways:

  • ArrayList is generally the better choice for most use cases
  • LinkedList excels at frequent insertions/deletions at the start
  • Consider memory usage and cache performance
  • Choose based on your specific access patterns
  • Follow best practices for optimal performance
About Techoral

Techoral is your go-to resource for Java development, Spring Boot, and test automation. We provide comprehensive guides, tutorials, and best practices for developers.

Popular Topics
Java Collections Data Structures ArrayList LinkedList Performance
Subscribe to Our Newsletter

Get the latest updates and exclusive content delivered to your inbox!