Skip to main content

Command Palette

Search for a command to run...

Java List Interface Explained: ArrayList, LinkedList, Stack & Vector

Updated
5 min read
Java List Interface Explained: ArrayList, LinkedList, Stack & Vector
P
Hey, I'm Prity — A Mech student who fell down the coding rabbit hole and never looked back. I started this blog because switching fields is hard. Nobody explains DSA assuming you don't have a CS background — so I'm doing it myself. Here you'll find DSA breakdowns, Java concepts, and real project stuff — written by someone who had to figure it all out from scratch. If you're also an "outsider" trying to break into tech, you're in the right place.

As a 2nd-year Mechanical Engineering student making the leap into Software Development, the Java Collections Framework initially felt like walking into a massive factory where every machine looked exactly the same. Why are there so many classes? Why do I need four different ways just to store a simple list of items? In mechanical design, you don’t use a heavy-duty bolt where a quick rivet will do. Software is no different.

If you’ve ever felt overwhelmed trying to choose between ArrayList, LinkedList, Stack, and Vector, you aren’t alone. This article strips away the confusing jargon. We will break down the Java List interface simply, look at the actual code, and map each class to its real-world Data Structures and Algorithms (DSA) use cases so you always know exactly which tool to grab from the toolbox.

What is the List Interface?

In Java, a List is an ordered collection that allows duplicate elements. Think of it like a numbered shelf in a warehouse — every item has a position (index), and you can have two identical items sitting side by side.

List is just an interface — it defines the rules. The actual classes (ArrayList, LinkedList, Stack, Vector) are the ones that follow those rules, each in their own way.

// You cannot do this:
List<String> list = new List<>(); // ❌ Interface can't be instantiated

// You do this instead:
List<String> list = new ArrayList<>(); // ✅

1. ArrayList — Your Go-To List

Think of ArrayList like a resizable array — imagine a shelf that automatically expands when you add more items.

Key Characteristics:

  • Backed by a dynamic array internally

  • Fast random access — get(index) is O(1)

  • Slow insertion/deletion in the middle — O(n)

  • Not thread-safe

import java.util.ArrayList;

ArrayList<String> student = new ArrayList<>();

// Adding elements
student.add("Prity");
student.add("Palak");
student.add("Soni");

// Accessing by index
System.out.println(student.get(0)); // Prity

// Removing an element
student.remove("Palak");

// Iterating
for(String student : student) {
    System.out.println(student);
}

When to use in DSA:

  • Storing results of a traversal

  • Dynamic arrays in sliding window problems

  • Anytime you need fast access by index

2. LinkedList — The Flexible Chain

Think of LinkedList like a chain of machine parts — each part holds its own data and a pointer to the next part. Unlike ArrayList, there's no fixed shelf — every element knows only its neighbour.

Key Characteristics:

  • Each element (node) stores data + pointer to next node

  • Fast insertion/deletion — O(1) at head/tail

  • Slow random access — O(n) to reach index

  • Can be used as both List and Deque

import java.util.LinkedList;

LinkedList<String> subjects = new LinkedList<>();

// Adding elements
subjects.add("Maths");
subjects.addFirst("Physics");  // adds at beginning
subjects.addLast("Chemistry"); // adds at end

// Accessing
System.out.println(subjects.getFirst()); // Physics
System.out.println(subjects.getLast());  // Chemistry

// Removing
subjects.removeFirst();

// Iterating
for(String subject : subjects) {
    System.out.println(subject);
}

When to use in DSA:

  • Implementing Queue or Stack

  • Problems involving frequent insertions/deletions

  • LRU Cache implementation

Confused about which one to pick? This table will make it crystal clear:

Operation ArrayList LinkedList
Access by index ✅ Fast O(1) ❌ Slow O(n)
Insert at middle ❌ Slow O(n) ✅ Fast O(1)
Memory Less More ( stores pointers )
Use in DSA Random access Frequent add/remove

3. Stack — Last In, First Out

Think of Stack like a stack of plates — you always add and remove from the top. The last plate you placed is the first one you pick up. This is called LIFO (Last In, First Out).

Key Characteristics:

  • Extends Vector class

  • Only top element is accessible

  • push(), pop(), peek() are main methods

  • Not recommended for new code — use ArrayDeque instead

import java.util.Stack;

Stack<Integer> stack = new Stack<>();

// Push elements
stack.push(10);
stack.push(20);
stack.push(30);

// Peek — see top without removing
System.out.println(stack.peek()); // 30

// Pop — remove from top
System.out.println(stack.pop()); // 30
System.out.println(stack.pop()); // 20

// Check if empty
System.out.println(stack.isEmpty()); // false

When to use in DSA:

  • Balanced parentheses problem

  • Undo/Redo operations

  • DFS (Depth First Search)

  • Next Greater Element problems

4. Vector — The Outdated Cousin

Vector is almost identical to ArrayList — but with one key difference: it is thread-safe. Every method in Vector is synchronized, which makes it slower.

Honest truth: In modern Java development and DSA, you will almost never use Vector. It exists for legacy reasons.

import java.util.Vector;

Vector<String> v = new Vector<>();
v.add("One");
v.add("Two");
System.out.println(v.get(0)); // One

Simple rule:

  • Need a list? → Use ArrayList

  • Need thread safety? → Use CopyOnWriteArrayList

  • Vector? → Basically never 😅

Which One Should You Actually Use?

Here's the quick decision guide — bookmark this!

Situation Use This
Default choice for most problems ArrayList
Frequent insert/delete at ends LinkedList
Need LIFO / undo functionality Stack (or ArrayDeque)
Legacy code only Vector
Implementing Queue in DSA LinkedList or ArrayDeque

Final Thoughts

Coming from Mechanical Engineering, I used to think more options = more confusion. But just like choosing between a bolt and a rivet, once you understand what each tool is built for, the choice becomes obvious.

Quick recap:

  • ArrayList — fast access, dynamic array, your default

  • LinkedList — fast insert/delete, node-based chain

  • Stack — LIFO, great for DSA problems

  • Vector — thread-safe but outdated, avoid in new code

This is Part 1 of my Java Collections Series. Next up — Queue Interface: ArrayDeque & PriorityQueue.

If this helped you, drop a reaction and follow for Part 2! 🚀