Collections Framework
List Interface
Analyze the List interface contracts, positional indexing operations, duplicates handling, and the ListIterator interface.
Interview: Focuses on ordered structures, index-based access exceptions, ListIterator bidirectional cursor movements, and subList structural changes.
The java.util.List interface represents an ordered collection (also known as a sequence). It gives the developer precise control over where elements are inserted, allows access by integer indexes, and permits duplicate elements.
Index Access
Enables index-based positioning: get(int), set(int, E), add(int, E), and remove(int).
ListIterator
Extends Iterator to allow bidirectional traversal (hasPrevious, previous) and element modifications during iteration.
subList View
Exposes a view of a portion of the list: subList(from, to). Modifications on this sublist propagate back to the backing list.
The subList View Contract
The subList(int fromIndex, int toIndex) method does not create a copy of the list. Instead, it returns a view backed by the original list:
- Structural updates made to the sublist (e.g. adding elements) are directly visible in the backing list.
- Structural mutation warning: If the backing list is structurally mutated directly (not through the sublist), the returned sublist becomes undefined, throwing
ConcurrentModificationExceptionon subsequent actions.
Common Pitfalls
- ConcurrentModification with subList: Modifying the parent list directly while keeping a reference to the active sublist, which invalidates the sublist's indices.
- Assuming index access is O(1): Using an index loop (
list.get(i)) on a LinkedList, which degrades toO(N²)due to linear lookup overhead.
Best Practices
- Use ListIterator for updates: Use
ListIteratorwhen you need to replace, add, or traverse backward while iterating. - Identify RandomAccess capability: Use
instanceof RandomAccessbefore iterating with index counters to check ifO(1)random access is supported.
Interview-Relevant Information
Q1: What is the difference between Iterator and ListIterator?
Answer: An Iterator allows only forward traversal and element deletion. A ListIterator is list-specific, allowing bidirectional traversal (previous/next), index tracking, element substitution (set), and insertion (add).
Q2: What happens if you mutate a parent list after creating a subList view?
Answer: Any structural mutation (additions or removals) on the parent list invalidates the sublist. Calling any method on the sublist afterwards will throw a ConcurrentModificationException.
Quick Checklist
Can you name four index-based access methods, explain how subList behaves when elements are added to it, and describe how ListIterator moves backward? If yes, you understand List interface.
Use Cases
Building pagination algorithms using the subList view window.
Creating text buffer utilities that require backward and forward traversal edits.
Common Mistakes
Treating subList as an isolated copy and mutating the parent list concurrently.
Iterating over lists of unknown type using index counters.