Access-order mode is enabled by the third constructor argument: new LinkedHashMap<>(initialCapacity, loadFactor, true). In this mode every get, getOrDefault, put (on an existing key), putIfAbsent, compute*, and merge moves the touched entry to the tail of the chain. The head therefore tracks the least-recently-used entry.
The constructor
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
There is no other way to switch modes — accessOrder is final and there's no setter. You must decide at construction time.
Map<String, Integer> m = new LinkedHashMap<>(16, 0.75f, true);
m.put("a", 1);
m.put("b", 2);
m.put("c", 3);
// chain: a, b, c (head -> tail)
m.get("a"); // moves "a" to tail
// chain: b, c, a
m.get("b"); // moves "b" to tail
// chain: c, a, b
How it works
HashMap.getNode calls a hook afterNodeAccess after a successful lookup. In plain HashMap that hook is a no-op; LinkedHashMap overrides it:
void afterNodeAccess(Node<K,V> e) {
Entry<K,V> last;
if (accessOrder && (last = tail) != e) {
Entry<K,V> p = (Entry<K,V>) e, b = p.before, a = p.after;
p.after = null;
if (b == null) head = a; else b.after = a;
if (a != null) a.before = b; else last = b;
if (last == null) head = p;
else { p.before = last; last.after = p; }
tail = p;
++modCount;
}
}
It detaches the node from its current position and re-links it at the tail. O(1), because the list is doubly-linked.
Why modCount increments
A get in access-order mode structurally modifies the chain. So iterating while another get happens will throw ConcurrentModificationException — even though no entries were added or removed:
Map<String, Integer> m = new LinkedHashMap<>(16, 0.75f, true);
m.put("a", 1); m.put("b", 2);
for (var e : m.entrySet()) {
m.get("a"); // CME -- iteration sees modCount change
}
This surprises people. In access-order mode, get is a mutating operation.
What does NOT move the entry
containsKey— does not callafterNodeAccess.putAllof a key that already exists in the source map (the receiving map sees normalput).entrySet().forEach(...)— iteration itself doesn't touch the chain.