In Java, ArrayList get is constant time and add is amortized constant. HashMap get and put and HashSet add and contains are constant time if the hash disperses well. TreeMap get and put are guaranteed log(n). PriorityQueue offer and poll are O(log(n)), and most ArrayDeque operations are amortized constant, according to the Javadoc.
Where these figures come from
Every statement below comes from the class documentation in the Java SE 25 Javadoc, the current long-term support release, read on November 5, 2026. Each section links to its class. Java states these in sentences rather than tables, so the wording and its conditions matter, and this page keeps them.
ArrayList
From ArrayList. The add operation "runs in amortized constant time, that is, adding n elements requires O(n) time."
| Operation | Cost | Note |
|---|---|---|
size, isEmpty, get, set | Constant | |
getFirst, getLast, removeLast | Constant | |
iterator, listIterator, reversed | Constant | Getting the iterator or view, not walking it. |
add, addLast | Amortized constant | A single add may cost more when the array grows. |
| All other operations | Linear, "roughly speaking" | This includes contains and remove(Object). |
LinkedList
LinkedList states no Big O at all. It says: "All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index." So there is no table here. In an interview, that second sentence is what you can cite: get(i) walks the list, it does not jump.
The Javadoc also gives a reason to avoid it for queues: ArrayDeque "is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue." ArrayList's page adds that its constant factor "is low compared to that for the LinkedList implementation."
HashMap
From HashMap. The condition matters: "constant-time performance for the basic operations (get and put), assuming the hash function disperses the elements properly among the buckets."
| Operation | Cost | Note |
|---|---|---|
get, put | Constant time | Assuming the hash disperses elements properly. |
| Iterating over a collection view | Proportional to capacity plus size | So do not set the initial capacity too high if you iterate. |
The same page explains what happens under pressure. When the map passes its load factor, it is rehashed to about twice the buckets, and the default load factor of .75 "offers a good tradeoff between time and space costs." It also warns that "using many keys with the same hashCode() is a sure way to slow down performance of any hash table," and that when keys are Comparable, the class may use their order to help break ties. It gives no Big O for that case, so neither does this page.
HashSet
From HashSet, with the same condition as HashMap.
| Operation | Cost | Note |
|---|---|---|
add, remove, contains, size | Constant time | Assuming the hash disperses elements properly. |
| Iterating | Proportional to size plus capacity | Capacity is that of the backing HashMap. |
TreeMap
From TreeMap. Unlike HashMap, this one has no condition: "guaranteed log(n) time cost."
| Operation | Cost | Note |
|---|---|---|
containsKey, get, put, remove | Guaranteed log(n) | |
Constructing from an unsorted Map | n*log(n) | |
Constructing from a SortedMap | Linear |
PriorityQueue
From PriorityQueue, which is the clearest of the seven. Note that remove() and remove(Object) are very different.
| Operation | Cost | Note |
|---|---|---|
offer, add, poll, remove() | O(log(n)) | The enqueuing and dequeuing methods. |
peek, element, size | Constant | The retrieval methods. |
remove(Object), contains(Object) | Linear | A heap cannot search by value. |
ArrayDeque
From ArrayDeque. This is the class to use for both stacks and queues, for the reason quoted above.
| Operation | Cost | Note |
|---|---|---|
| Most operations | Amortized constant | Everything not listed below, such as addFirst, addLast, pollFirst and pollLast. |
remove, removeFirstOccurrence, removeLastOccurrence | Linear | |
contains, iterator.remove(), bulk operations | Linear |
The choices in code
Each line here is one of the choices above: ArrayDeque for a queue, a bounded PriorityQueue for top k, and HashMap with merge for counts.
Java
import java.util.*;
class CollectionChoices {
// Fewest steps in an unweighted graph: ArrayDeque as the queue.
static int fewestSteps(Map<Integer, List<Integer>> graph, int start, int goal) {
Deque<int[]> queue = new ArrayDeque<>();
Set<Integer> seen = new HashSet<>(List.of(start));
queue.add(new int[] {start, 0});
while (!queue.isEmpty()) {
int[] cur = queue.poll();
if (cur[0] == goal) return cur[1];
for (int next : graph.getOrDefault(cur[0], List.of())) {
if (seen.add(next)) queue.add(new int[] {next, cur[1] + 1});
}
}
return -1;
}
// The k largest values: a min-heap holding only k items, O(n log k).
static List<Integer> topK(int[] values, int k) {
PriorityQueue<Integer> heap = new PriorityQueue<>();
for (int v : values) {
heap.offer(v);
if (heap.size() > k) heap.poll(); // evict the smallest
}
return new ArrayList<>(heap);
}
// Counting with a HashMap, then reading in key order with a TreeMap.
static SortedMap<String, Integer> sortedCounts(List<String> words) {
Map<String, Integer> counts = new HashMap<>();
for (String w : words) counts.merge(w, 1, Integer::sum);
return new TreeMap<>(counts); // n*log(n) to build
}
}How to say it out loud
I'll use a HashMap for the counts, since get and put are constant time as long as the hash disperses keys well, and String's hash should be fine here. For the queue I'll use ArrayDeque rather than LinkedList, because its operations are amortized constant and the docs say it's likely to be faster as a queue. That makes the whole thing O(n) time and O(n) space. If I needed keys in sorted order, I'd switch to a TreeMap and pay log n per operation, which has a guaranteed bound.
Saying "assuming the hash disperses well" is the Java version of saying "on average," and it is the condition an interviewer is listening for. You can practice it in a coding mock interview, and the Big O cheat sheet covers the structures in general.
What the docs do not state
These have no figure in the class documentation, so they have no row here:
LinkedList: no Big O for any operation, includingaddFirstandremoveFirst.HashMap: no figure forremoveorcontainsKey, since "basic operations" names only get and put, and no worst case.TreeMap: no figure forfirstKey,floorKey,ceilingKeyand the other navigation methods.ArrayList: the sentence onadddoes not separateadd(E)fromadd(int, E), so neither does the table.
Frequently asked questions
What is the time complexity of HashMap get in Java?
The Javadoc says get and put are constant time, assuming the hash function disperses the elements properly among the buckets. So state that condition along with the figure. It also warns that many keys with the same hashCode slow down any hash table. It does not give a worst-case figure.
Is HashMap or TreeMap faster in Java?
HashMap gives constant-time get and put, if the hash disperses well. TreeMap gives a guaranteed log(n) for containsKey, get, put and remove, and it keeps keys sorted. Use HashMap unless you need sorted keys or range queries, and say that is the reason when you choose TreeMap.
Should I use LinkedList or ArrayDeque for a queue in Java?
Use ArrayDeque. Its Javadoc says it is likely to be faster than LinkedList when used as a queue, and faster than Stack when used as a stack, and most of its operations run in amortized constant time. LinkedList states no Big O, only that indexed operations traverse the list.