DevNotes
Support
Collection Framework · Chapter 03

List Interface

Ordered, index-based collections — List methods, ListIterator, Arrays.asList vs List.of and implementation choices.

◷ 6 min read§ 16 sections? 7 interview questions{ } 20 code examples

#Introduction

The List interface is one of the most frequently used collection types in Java. Almost every Java application uses ArrayList or LinkedList, so interviewers expect you to know the List interface thoroughly.

#What is List?

A List is an ordered collection that:

  • Allows duplicate elements
  • Allows null elements (implementation dependent)
  • Supports positional (index-based) access
  • Preserves insertion order

Package:

Java
java.util.List

Declaration:

Java
public interface List<E> extends Collection<E>
  • Iterable
    • Collection
      • List
        • ArrayList
        • LinkedList
        • Vector
          • Stack
Hierarchy

#Characteristics of List

1. Ordered Collection

Elements are stored in insertion order.

Java
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("C++");
System.out.println(list);
Output
[Java, Python, C++]

The order remains exactly the same.

2. Allows Duplicates

Unlike Set, List allows duplicate values.

Java
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(10);
list.add(20);
System.out.println(list);
Output
[10, 10, 20]

3. Allows Null Values

Most List implementations allow multiple null values.

Java
List<String> list = new ArrayList<>();
list.add(null);
list.add(null);
System.out.println(list);
Output
[null, null]

4. Index-Based Access

Every element has an index.

Index012
ValueABC
Java
list.get(1);
Output
B

#Why List?

Suppose you're developing an online shopping application. Cart items: 1. Laptop, 2. Mouse, 3. Keyboard.

  • Order matters.
  • Duplicates are allowed.
  • You need index-based access.

A perfect use case for List.

#List Interface Methods

Apart from the Collection methods, List introduces many new methods.

add(int index, E element)

Adds an element at a specific position.

Java
List<String> list = new ArrayList<>();
list.add("A");
list.add("C");
list.add(1, "B");
System.out.println(list);
Output
[A, B, C]

get()

Returns the element at an index.

Java
String value = list.get(2);
Output
C

Time complexity (interview favourite): ArrayList → O(1), LinkedList → O(n).

set()

Replaces an element and returns the old value.

Java
list.set(1, "Java");
System.out.println(list);
Output
[A, Java, C]

remove(int index)

Removes the element at an index.

Java
list.remove(1);
Output
[A, C]

indexOf()

Returns the first occurrence.

Java
List<Integer> list = Arrays.asList(10, 20, 30, 20);
System.out.println(list.indexOf(20));
Output
1

lastIndexOf()

Returns the last occurrence.

Java
System.out.println(list.lastIndexOf(20));
Output
3

subList()

Returns a view of the original list.

Java
List<Integer> list = Arrays.asList(10, 20, 30, 40, 50);
System.out.println(list.subList(1, 4));
Output
[20, 30, 40]

listIterator()

Returns a ListIterator<E>. Unlike Iterator, a ListIterator can:

  • Move forward
  • Move backward
  • Update elements
  • Add elements
  • Remove elements
Java
ListIterator<String> itr = list.listIterator();

while (itr.hasNext()) {
    System.out.println(itr.next());
}

#Iterator vs ListIterator

FeatureIteratorListIterator
ForwardYesYes
BackwardNoYes
AddNoYes
SetNoYes
RemoveYesYes
Only for ListNoYes

#Array vs List

ArrayList
Fixed SizeDynamic
Primitive SupportObjects Only
FasterFlexible
No Built-in MethodsRich API
Cannot ResizeAutomatically Resizes

#List Implementations

Java provides four major implementations, each with different characteristics. We'll study each in separate chapters.

ImplementationInternallyBest for / Notes
ArrayListResizable arrayRandom access, read-heavy operations
LinkedListDoubly linked listFrequent insertions and deletions
VectorResizable arraySynchronized methods: thread-safe but slower than ArrayList
StackExtends VectorLIFO: push(), pop(), peek(). Legacy — prefer Deque today

#Equality in List

Java
List<Integer> l1 = Arrays.asList(1, 2, 3);
List<Integer> l2 = Arrays.asList(1, 2, 3);
System.out.println(l1.equals(l2));
Output
true

Lists compare order and elements. If the order changes ([1, 2, 3] vs [2, 1, 3]), the result is false. (Interview favourite.)

hashCode() in List

Contract: equal lists → equal hash codes. The hash code depends on order and elements.

#Immutable List

Java 9 introduced List.of():

Java
List<String> list = List.of("A", "B", "C");
list.add("D");
Output
UnsupportedOperationException

#Arrays.asList() vs List.of()

Interview favourite.

Arrays.asList()

Java
List<String> list = Arrays.asList("A", "B");
  • Fixed-size
  • Allows set()
  • Backed by the original array
  • Allows null values

List.of()

Java
List<String> list = List.of("A", "B");
  • Completely immutable
  • Does not allow add(), remove() or set()
  • Does not allow null values

Arrays.asList() Example

Java
List<String> list = Arrays.asList("A", "B");
list.set(0, "Java");
System.out.println(list);
Output
[Java, B]

Works. But list.add("C"); throws an exception.

List.of() Example

Java
List<String> list = List.of("A", "B");
list.set(0, "Java");
Output
UnsupportedOperationException

#Time Complexity

OperationArrayListLinkedList
add(end)O(1)*O(1)
add(index)O(n)O(n)
get(index)O(1)O(n)
remove(index)O(n)O(n)
contains()O(n)O(n)
iterationO(n)O(n)

*Amortized O(1)

#Common Mistakes

  • list.get(100); on a smaller list → throws IndexOutOfBoundsException.
  • List.of("A").add("B"); → UnsupportedOperationException.
  • Arrays.asList(1, 2, 3).add(4); → UnsupportedOperationException.

#Real-world Use Cases

Use caseType
Student listList<Student> students;
Shopping cartList<Product> cart;
Search resultsList<Employee> employees;
API responseList<UserDTO> users;
Database recordsList<Order> orders;

#Frequently Asked Interview Questions

Q1Difference between List and Set?
ListSet
Allows duplicatesNo duplicates
OrderedGenerally unordered (except LinkedHashSet / TreeSet)
Index-basedNo index
Q2Which List implementation is fastest?

It depends:

  • Reading → ArrayList
  • Insertion/deletion (middle, frequent structural changes) → LinkedList
  • Thread-safe → Vector
Q3Why does List allow duplicates?

Because List is designed to preserve insertion order and sequence. Duplicate values are considered valid elements.

Q4Difference between Arrays.asList() and List.of()?
Arrays.asList()List.of()
Fixed-sizeImmutable
Allows set()No set()
Allows nullNo null
Backed by arrayIndependent immutable collection
Q5Difference between Iterator and ListIterator?

ListIterator supports bidirectional traversal and modification (add(), set()), while Iterator supports only forward traversal and element removal.

Q6What happens if you access an invalid index?

An IndexOutOfBoundsException is thrown.

Q7Why is ArrayList generally preferred over LinkedList?

Because most applications perform far more reads than insertions/deletions in the middle. ArrayList provides O(1) random access, is cache-friendly due to contiguous memory, and usually offers better overall performance.

#Chapter Summary

  • List extends the Collection interface.
  • Lists preserve insertion order.
  • Lists allow duplicate and (implementation-dependent) null elements.
  • Lists provide index-based operations such as get(), set(), add(index) and remove(index).
  • ListIterator is more powerful than Iterator.
  • Arrays.asList() returns a fixed-size list, while List.of() returns an immutable list.
  • Choose ArrayList for fast random access and LinkedList when frequent insertions/deletions are required.