25. The List API
Table of Contents
- 25.1 Characteristics of Lists
- 25.2 Creating Lists Constructors
- 25.3 Factory Methods
- 25.4 Core List Operations
- 25.5 contains, equals and hashCode
- 25.6 Iterating Through a List
- 25.7 The subList Method
- 25.8 Summary Table of Important Operations
In the Collections Framework, a List represents an ordered, index-based, duplicate-allowing collection.
The List interface extends Collection and is implemented by:
List
├── ArrayList (Resizable array — fast random access, slower inserts/removals in the middle)
├── LinkedList (Doubly-linked list — fast inserts/removals, slower random access)
└── Vector (Legacy synchronized list — rarely used today)
Note
Vector is legacy and synchronized — avoid unless explicitly required.
25.1 Characteristics of Lists
- Ordered — elements preserve insertion order.
- Indexed — accessible via
get(int)andset(int,E). - Allow duplicates —
Listdoes not enforce uniqueness. - Can contain
null— unless using special implementations.
25.2 Creating Lists (Constructors)
25.2.1 ArrayList Constructors
List<String> a1 = new ArrayList<>();
List<String> a2 = new ArrayList<>(50); // initial capacity
List<String> a3 = new ArrayList<>(List.of("A", "B"));
Note
Initial capacity is not a size. It just decides how many elements the internal array can hold before resizing.
25.2.2 LinkedList Constructors
List<String> l1 = new LinkedList<>();
List<String> l2 = new LinkedList<>(List.of("A", "B"));
Note
LinkedList also implements Deque.
25.3 Factory Methods
25.3.1 List.of() (immutable)
List<String> list1 = List.of("A", "B", "C");
list1.add("X"); // ❌ UnsupportedOperationException
list1.set(0, "Z"); // ❌ UnsupportedOperationException
Note
All List.of() lists:
- reject nulls
- are immutable
- throw UOE on structural modification
25.3.2 List.copyOf() (immutable copy)
List<String> src = new ArrayList<>();
src.add("Hello");
List<String> copy = List.copyOf(src); // immutable snapshot
25.3.3 Arrays.asList() (fixed-size list)
String[] arr = {"A", "B"};
List<String> list = Arrays.asList(arr);
list.set(0, "Z"); // OK
list.add("X"); // ❌ UOE — size is fixed
Note
The list is backed by the array: modifying one affects the other.
25.4 Core List Operations
25.4.1 Adding Elements
list.add("A");
list.add(1, "B"); // insert at index
list.addAll(otherList);
list.addAll(2, otherList);
25.4.2 Accessing Elements
String x = list.get(0);
list.set(1, "NewValue");
Note
get() throws IndexOutOfBoundsException for invalid indices.
If you try to update an element in an empty List, even at index 0, you get an IndexOutOfBoundsException
List<Integer> list = new ArrayList<Integer>();
list.add(3);
list.add(5);
System.out.println(list.toString());
list.clear();
list.set(0, 2);
Output
[3, 5]
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
Warning
Calling get/set with an invalid index throws IndexOutOfBoundsException
25.4.3 Removing Elements
list.remove(0); // remove(int index) — removes by index; remove(Object) — removes first equal element
list.remove("A"); // removes first occurrence
list.removeIf(s -> s.startsWith("X"));
list.clear();
25.4.4 Important Behaviors and Characteristics
| Operation | Behavior | Exception(s) |
|---|---|---|
add(E) |
always appends | — |
add(int,E) |
shifts elements right | IndexOutOfBoundsException |
get(int) |
constant-time for ArrayList, linear for LinkedList | IndexOutOfBoundsException |
set(int,E) |
replaces element | IndexOutOfBoundsException |
remove(int) |
shifts elements left | IndexOutOfBoundsException |
remove(Object) |
removes first equal element | — |
25.5 contains(), equals(), and hashCode()
25.5.1 contains()
Method contains() uses .equals() on elements.
25.5.2 Equality of Lists
List.equals() performs element-wise comparison in order.
List<String> a = List.of("A", "B");
List<String> b = List.of("A", "B");
System.out.println(a.equals(b)); // true
Note
- Order matters.
- Type of list does NOT matter.
25.5.3 hashCode()
Computed based on the contents.
25.6 Iterating Through a List
25.6.1 Classic For Loop
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
25.6.2 Enhanced For Loop
for (String s : list) {
System.out.println(s);
}
25.6.3 Iterator & ListIterator
Iterator<String> it = list.iterator();
while (it.hasNext()) { System.out.println(it.next()); }
ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) {
if (lit.next().equals("A")) lit.set("Z");
}
Warning
All standard List iterators are fail-fast: structural modification outside iterator causes ConcurrentModificationException.
Note
Only ListIterator supports bidirectional traversal and modification.
25.7 The subList() Method
subList() creates a view of a portion of the list, not a copy.
Modifying either list can modify the other.
25.7.1 Syntax
List<E> subList(int fromIndex, int toIndex);
25.7.2 Rules
| Rule | Explanation |
|---|---|
| fromIndex inclusive | element at fromIndex is included |
| toIndex exclusive | element at toIndex is NOT included |
| The view is backed by original list | modifying one modifies the other |
| Structural modification of parent invalidates the subList | → ConcurrentModificationException |
25.7.3 Examples
List<String> list = new ArrayList<>(List.of("A", "B", "C", "D"));
List<String> view = list.subList(1, 3);
// view = ["B", "C"]
view.set(0, "X");
// list = ["A", "X", "C", "D"]
// view = ["X", "C"]
25.7.4 Modifying the parent list invalidates the view
List<String> list = new ArrayList<>(List.of("A","B","C","D"));
List<String> view = list.subList(1, 3);
list.add("E"); // structural change to parent list
view.get(0); // ❌ ConcurrentModificationException
25.7.5 Modifying the subList modifies the parent
view.remove(1);
// removes "C" from both view and parent list
25.7.6 Clearing the subList clears part of the parent list
view.clear();
// removes indices 1 and 2 from the parent
25.7.7 Common Pitfalls
- Assuming subList is independent: it is a view, not a copy
- Assuming subList allows resizing: works only on modifiable parent lists.
- Forgetting that parent modifications invalidate results in ConcurrentModificationException
- Incorrect index expectations: End index is exclusive
25.8 Summary Table of Important Operations
| Operation | ArrayList | LinkedList | Immutable Lists |
|---|---|---|---|
add(E) |
fast | fast | ❌ unsupported |
add(index,E) |
slow (shift) | fast | ❌ |
get(index) |
fast | slow | fast |
remove(index) |
slow | slow (unless removing first/last) | ❌ |
remove(Object) |
slower | slower | ❌ |
set(index,E) |
fast | slow | ❌ |
iterator() |
fast | fast | fast |
listIterator() |
fast | fast | fast |
contains(Object) |
O(n) | O(n) | O(n) |