Java Collections Choice
Choosing the right Java collection means matching the data structure to the required ordering, uniqueness, access pattern, and key-value needs. For junior backend interviews, the core choices are `List`, `Set`, and `Map`, with common implementations such as `ArrayList`, `HashSet`, and `HashMap`.
`List` represents an ordered sequence and permits duplicate elements. Use it when position matters or when you need indexed access; `ArrayList` is the usual default when you do not need frequent insertions or removals in the middle of the sequence.
`Set` represents a collection of unique elements. Use it when membership and uniqueness matter more than element position; `HashSet` is a common general-purpose implementation, while `LinkedHashSet` preserves insertion order and `TreeSet` maintains sorted order.
`Map` stores associations between keys and values rather than a simple sequence of elements. Use it when you need to retrieve a value from a key; `HashMap` is the usual general-purpose choice, while `LinkedHashMap` preserves insertion order and `TreeMap` keeps keys sorted.
The implementation matters because its performance and ordering behavior differ. For example, `ArrayList` provides fast indexed reads, while inserting into the middle requires shifting elements; hash-based sets and maps normally provide expected constant-time lookup, assuming good hash distribution.
A good interview answer starts with the requirement rather than memorizing one collection as universally best. State whether you need duplicates, ordering, sorting, indexed access, or key-based lookup, then choose the simplest collection that satisfies those requirements.
Key points
- Use `List` for ordered sequences and duplicates.
- Use `Set` when elements must be unique.
- Use `Map` for key-to-value associations.
- Prefer `ArrayList`, `HashSet`, and `HashMap` as common defaults when their semantics fit.
- Choose `LinkedHashSet` or `LinkedHashMap` when insertion order must be retained.
- Choose sorted collections such as `TreeSet` or `TreeMap` when ordered-by-comparison traversal is required.
Interview questions
How do you decide whether to use a List, Set, or Map?
Start with the data relationship you need. Use a `List` for an ordered sequence that can contain duplicates, a `Set` for unique elements, and a `Map` when values are retrieved using keys. Then consider secondary requirements such as insertion order, sorting, or indexed access. Finally, select an implementation whose behavior matches those requirements.
What is the difference between ArrayList and LinkedList?
Both implement `List`, but they use different internal structures. `ArrayList` is backed by a resizable array, making indexed reads efficient, while `LinkedList` is node-based and does not provide constant-time indexed access. `LinkedList` can efficiently insert or remove at a known node, but finding that position may itself require traversal. In many ordinary application cases, `ArrayList` is the simpler default.
Does HashSet preserve insertion order?
No. `HashSet` does not guarantee iteration order, so application code should not depend on the order in which elements appear during iteration. If insertion order is required, use `LinkedHashSet`. If sorted order is required, consider `TreeSet` instead.
What are the typical lookup complexities of ArrayList, HashSet, and HashMap?
An `ArrayList` provides constant-time indexed access, but searching for an arbitrary value is linear in the number of elements. `HashSet` membership and `HashMap` key lookup are expected to be constant time under normal hashing assumptions. These are not absolute guarantees because hashing behavior, collisions, and implementation details affect performance. For sorted tree-based collections, basic search, insertion, and removal are typically logarithmic.
Why should code usually depend on the Collection interface rather than a concrete implementation?
Programming to an interface separates what the code needs from how the collection is implemented. If a method only requires list behavior, declaring it as `List<T>` makes the implementation easier to replace later. For example, callers can work with `List` while the implementation chooses `ArrayList` based on its performance and behavior. This also communicates the required capabilities more clearly.