Maps in Java: Difference between revisions
From charlesreid1
(Fix critical errors: Map is an interface not abstract class; add missing implementations (ConcurrentHashMap, WeakHashMap, IdentityHashMap, EnumMap); fix Hashtable description; add interface hierarchy (SortedMap, NavigableMap, ConcurrentMap); consistent Java 8 doc links; remove informal placeholder text; add comparison table; improve HashMap description with tree-bin details (via update-page on MediaWiki MCP Server)) |
|||
| Line 1: | Line 1: | ||
=Notes= | =Notes= | ||
Maps are implemented in Java as part of the Collections | Maps are implemented in Java as part of the Java Collections Framework. Although maps do not extend the {{Code|java.util.Collection}} interface, they are part of the overall Collections Framework. | ||
Here is a link to the OpenJDK source code, util module: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/ | Here is a link to the OpenJDK source code, {{Code|java.util}} module: | ||
* JDK 8: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/ | |||
* JDK 11+: https://github.com/openjdk/jdk/tree/master/src/java.base/share/classes/java/util | |||
The Java Collections | The Java Collections Framework provides a rich hierarchy of map interfaces and concrete implementations. | ||
== | ==Interface hierarchy== | ||
The | The map-related interfaces form the following hierarchy: | ||
{| class="wikitable" | |||
|- | |||
! Interface !! Description | |||
|- | |||
| {{Code|java.util.Map<K,V>}} || The root interface. Defines the contract that all map implementations must satisfy. '''This is an interface, not an abstract class.''' | |||
|- | |||
| {{Code|java.util.SortedMap<K,V>}} || Extends {{Code|Map}}. A map whose keys are stored in sorted (ascending) order. Provides methods like {{Code|firstKey()}}, {{Code|lastKey()}}, {{Code|subMap()}}, {{Code|headMap()}}, and {{Code|tailMap()}}. | |||
|- | |||
| {{Code|java.util.NavigableMap<K,V>}} || Extends {{Code|SortedMap}}. Adds navigation methods returning the closest matches for given search targets: {{Code|lowerEntry()}}, {{Code|floorEntry()}}, {{Code|ceilingEntry()}}, {{Code|higherEntry()}}, as well as {{Code|descendingMap()}} and {{Code|descendingKeySet()}}. | |||
|- | |||
| {{Code|java.util.concurrent.ConcurrentMap<K,V>}} || Extends {{Code|Map}}. Adds thread-safe atomic operations such as {{Code|putIfAbsent()}}, {{Code|remove()}} (key+value form), {{Code|replace()}}, and {{Code|compute()}} methods. | |||
|- | |||
| {{Code|java.util.concurrent.ConcurrentNavigableMap<K,V>}} || Extends both {{Code|ConcurrentMap}} and {{Code|NavigableMap}}. Provides a thread-safe navigable map. | |||
|} | |||
===Map interface (the root)=== | |||
{{Code|java.util.Map<K,V>}} is the top-level contract for maps. It is an '''interface''', not an abstract class. It declares all the fundamental map operations. | |||
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/Map.java | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/Map.html | |||
{{Code|Map}} defines core methods including: | |||
* {{Code|size()}}, {{Code|isEmpty()}} | |||
* {{Code|get(Object key)}}, {{Code|put(K key, V value)}}, {{Code|remove(Object key)}} | |||
* {{Code|containsKey(Object key)}}, {{Code|containsValue(Object value)}} | |||
* {{Code|keySet()}}, {{Code|values()}}, {{Code|entrySet()}} | |||
* {{Code|putAll(Map m)}}, {{Code|clear()}} | |||
Java 8 added default method implementations for functional-style operations: | |||
* {{Code|getOrDefault(Object key, V defaultValue)}} | |||
* {{Code|putIfAbsent(K key, V value)}} | |||
* {{Code|replace(K key, V oldValue, V newValue)}} and {{Code|replace(K key, V value)}} | |||
* {{Code|replaceAll(BiFunction)}} | |||
* {{Code|computeIfAbsent(K key, Function)}} | |||
* {{Code|computeIfPresent(K key, BiFunction)}} | |||
* {{Code|compute(K key, BiFunction)}} | |||
* {{Code|merge(K key, V value, BiFunction)}} | |||
* {{Code|forEach(BiConsumer)}} | |||
==AbstractMap== | ==AbstractMap== | ||
{{Code|java.util.AbstractMap<K,V>}} is an abstract class that implements the {{Code|Map}} interface. It provides skeletal implementations of most {{Code|Map}} operations, minimizing the effort required to create a concrete map implementation. Subclasses need only implement {{Code|entrySet()}} to have a fully functioning (unmodifiable) map; implementing {{Code|put()}} as well yields a modifiable map. | |||
Source: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/AbstractMap.java | Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/AbstractMap.java | ||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/AbstractMap.html | |||
Constructor: | Constructor (protected, for subclass use only): | ||
<pre> | <pre> | ||
| Line 35: | Line 74: | ||
</pre> | </pre> | ||
{{Code|containsValue}} method — iterates the entry set, handling null values safely: | |||
<pre> | <pre> | ||
| Line 57: | Line 96: | ||
</pre> | </pre> | ||
{{Code|remove}} method — uses an explicit {{Code|correctEntry}} pointer to track the entry to delete, then calls the iterator's {{Code|remove()}}: | |||
<pre> | <pre> | ||
| Line 85: | Line 124: | ||
</pre> | </pre> | ||
==Concrete implementations== | |||
== | |||
HashMap | ===HashMap=== | ||
{{Code|java.util.HashMap<K,V>}} is the standard general-purpose hash-table-based map implementation. It provides O(1) expected-time performance for {{Code|get}} and {{Code|put}} operations, assuming the hash function disperses keys properly among buckets. | |||
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/HashMap.java | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html | |||
Key characteristics: | |||
* Extends {{Code|AbstractMap}} and implements {{Code|Map}}, {{Code|Cloneable}}, {{Code|Serializable}}. | |||
* Uses separate chaining with bins (linked lists). Starting in Java 8, when a bin accumulates enough collisions ({{Code|TREEIFY_THRESHOLD}} = 8), the bin is converted to a balanced tree ({{Code|TreeNode}}), improving worst-case performance from O(n) to O(log n). | |||
* Permits {{Code|null}} keys and {{Code|null}} values. | |||
* '''Not synchronized'''. For a thread-safe counterpart, use {{Code|Collections.synchronizedMap()}} or {{Code|ConcurrentHashMap}}. | |||
* Two configurable parameters affect performance: '''initial capacity''' (the number of buckets at creation) and '''load factor''' (the fraction of capacity at which the map is resized; default 0.75). | |||
* The iterators returned by {{Code|keySet()}}, {{Code|values()}}, and {{Code|entrySet()}} are fail-fast: if the map is structurally modified after an iterator is created (except through the iterator's own {{Code|remove}} method), the iterator throws {{Code|ConcurrentModificationException}}. | |||
From the comments | From the implementation comments describing the tree-bin transition: | ||
<pre> | <pre> | ||
| Line 118: | Line 157: | ||
</pre> | </pre> | ||
==TreeMap== | ===TreeMap=== | ||
{{Code|java.util.TreeMap<K,V>}} is a Red-Black tree-based implementation of the {{Code|NavigableMap}} interface. It stores keys in sorted (natural or Comparator-defined) order, yielding O(log n) time for {{Code|get}}, {{Code|put}}, {{Code|remove}}, {{Code|containsKey}}, and most other operations. | |||
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/TreeMap.java | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html | |||
Key characteristics: | |||
* Extends {{Code|AbstractMap}} and implements {{Code|NavigableMap}}, {{Code|Cloneable}}, {{Code|Serializable}}. | |||
* Maintains keys in ascending sorted order, either by their natural ordering ({{Code|Comparable}}) or by a {{Code|Comparator}} supplied at construction time. | |||
* Provides efficient access to min and max keys via {{Code|firstKey()}} / {{Code|firstEntry()}} and {{Code|lastKey()}} / {{Code|lastEntry()}} (both O(log n)). | |||
* {{Code|NavigableMap}} methods like {{Code|lowerKey()}}, {{Code|floorKey()}}, {{Code|ceilingKey()}}, {{Code|higherKey()}} allow range queries — each O(log n). | |||
* Does '''not''' permit {{Code|null}} keys (a {{Code|NullPointerException}} is thrown when a {{Code|null}} key is used with natural ordering, or when the {{Code|Comparator}} does not allow {{Code|null}}). | |||
* '''Not synchronized'''. | |||
* Slower than {{Code|HashMap}} for basic lookup/insertion (O(log n) vs. O(1) expected), but preferred when sorted traversal or range queries are needed. | |||
==LinkedHashMap== | ===LinkedHashMap=== | ||
{{Code|java.util.LinkedHashMap<K,V>}} extends {{Code|HashMap}} and maintains a '''doubly-linked list''' running through all entries. This preserves iteration order — either '''insertion order''' (default) or '''access order''' (configurable via constructor). | |||
Source: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/LinkedHashMap.java | Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/LinkedHashMap.java | ||
Documentation: | Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html | ||
Key characteristics: | |||
* Extends {{Code|HashMap}} and implements {{Code|Map}}. | |||
* Performance is slightly lower than {{Code|HashMap}} due to the overhead of maintaining the linked list, but iteration over the entry set is proportional to size (not capacity), unlike {{Code|HashMap}}. | |||
* When constructed in '''access-order''' mode ({{Code|new LinkedHashMap(initialCapacity, loadFactor, true)}}), it is suitable for building an LRU (least-recently-used) cache: override {{Code|removeEldestEntry()}} to evict the oldest entry when the map exceeds a desired size. | |||
* '''Not synchronized'''. | |||
Class declaration: | |||
<pre> | <pre> | ||
| Line 143: | Line 197: | ||
</pre> | </pre> | ||
The doubly-linked list is managed with {{Code|head}} and {{Code|tail}} pointers (line 199 of the source): | |||
<pre> | <pre> | ||
| Line 157: | Line 211: | ||
</pre> | </pre> | ||
Private utility method for linking a node at the end of the list (line 217): | |||
<pre> | <pre> | ||
// link at the end of list | // link at the end of list | ||
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) { | private void linkNodeLast(LinkedHashMap.Entry<K,V> p) { | ||
| Line 175: | Line 227: | ||
</pre> | </pre> | ||
==Hashtable== | ===Hashtable=== | ||
{{Code|java.util.Hashtable<K,V>}} is a legacy hash-table-based map implementation that predates the Collections Framework. It was retrofitted to implement {{Code|Map}} when the Collections Framework was introduced in Java 1.2. | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/Hashtable.html | |||
Key characteristics: | |||
* '''Synchronized''' — all methods are thread-safe through intrinsic locking on the {{Code|Hashtable}} instance. This makes it slower than {{Code|HashMap}} for single-threaded use. | |||
* Does '''not''' permit {{Code|null}} keys or {{Code|null}} values (throws {{Code|NullPointerException}}). | |||
* Largely superseded by {{Code|HashMap}} (non-synchronized) and {{Code|ConcurrentHashMap}} (for concurrent use). {{Code|Hashtable}} is considered a legacy class; new code should prefer {{Code|HashMap}} or {{Code|ConcurrentHashMap}}. | |||
===ConcurrentHashMap=== | |||
{{Code|java.util.concurrent.ConcurrentHashMap<K,V>}} is a highly concurrent, thread-safe hash-table-based map. Unlike {{Code|Hashtable}} (which locks the entire map for every operation), {{Code|ConcurrentHashMap}} uses fine-grained locking (lock striping) to allow concurrent reads and a configurable number of concurrent writes. | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html | |||
Key characteristics: | |||
* Implements {{Code|ConcurrentMap}} and {{Code|Serializable}}. | |||
* Does '''not''' permit {{Code|null}} keys or {{Code|null}} values. | |||
* Obsoletes {{Code|Hashtable}} for concurrent use cases. Provides dramatically better scalability under contention. | |||
* Supports atomic compound operations: {{Code|putIfAbsent()}}, {{Code|remove(key, value)}}, {{Code|replace(key, oldValue, newValue)}}. | |||
* Iterators are '''weakly consistent''': they reflect the state of the map at some point since the iterator was created, do not throw {{Code|ConcurrentModificationException}}, and may proceed concurrently with other operations. | |||
* Bulk operations ({{Code|forEach}}, {{Code|search}}, {{Code|reduce}}) support parallelism via the common {{Code|ForkJoinPool}}. | |||
===WeakHashMap=== | |||
{{Code|java.util.WeakHashMap<K,V>}} is a hash-table-based map whose keys are held via '''weak references'''. When a key is no longer strongly reachable from elsewhere in the application, the garbage collector may reclaim it, and the corresponding entry is automatically removed from the map. | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/WeakHashMap.html | |||
This is useful for canonicalizing or caching mappings where the lifetime of the entry should not prevent garbage collection of the key. Example use case: storing metadata about objects without preventing those objects from being garbage-collected. | |||
===IdentityHashMap=== | |||
{{Code|java.util.IdentityHashMap<K,V>}} is a hash-table-based map that uses '''reference equality''' ({{Code|==}}) instead of object equality ({{Code|.equals()}}) when comparing keys. This violates the general {{Code|Map}} contract — it is intended for rare use cases where reference-equality semantics are required, such as topology-preserving object graphs, serialization, or proxy objects. | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/IdentityHashMap.html | |||
===EnumMap=== | |||
{{Code|java.util.EnumMap<K extends Enum<K>,V>}} is a specialized map implementation for enum keys. Internally, it uses a compact array indexed by the enum's ordinal values, yielding extremely fast O(1) performance with minimal memory overhead. | |||
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/EnumMap.html | |||
Key characteristics: | |||
* All keys in an {{Code|EnumMap}} must belong to a single enum type, specified at construction time. | |||
* Does '''not''' permit {{Code|null}} keys; permits {{Code|null}} values. | |||
* Iteration order follows the natural order of the enum constants (the order in which they are declared). | |||
* Extremely efficient: uses a plain Java array internally (one array slot per enum constant), avoiding hashing overhead entirely. | |||
* '''Not synchronized'''. | |||
==Comparison of implementations== | |||
{| class="wikitable" | |||
|- | |||
! Implementation !! Interface !! Underlying structure !! Ordering !! {{Code|null}} keys !! {{Code|null}} values !! Thread-safe !! Typical {{Code|get}} / {{Code|put}} | |||
|- | |||
| {{Code|HashMap}} || {{Code|Map}} || Hash table (+ tree bins) || None || Yes || Yes || No || O(1) expected | |||
|- | |||
| {{Code|LinkedHashMap}} || {{Code|Map}} || Hash table + doubly-linked list || Insertion or access order || Yes || Yes || No || O(1) expected | |||
|- | |||
| {{Code|TreeMap}} || {{Code|NavigableMap}} || Red-Black tree || Sorted (natural or Comparator) || No* || Yes || No || O(log n) | |||
|- | |||
| {{Code|Hashtable}} || {{Code|Map}} || Hash table || None || No || No || Yes (per-method) || O(1) expected | |||
|- | |||
| {{Code|ConcurrentHashMap}} || {{Code|ConcurrentMap}} || Hash table (lock-striped) || None || No || No || Yes (non-blocking reads) || O(1) expected | |||
|- | |||
| {{Code|WeakHashMap}} || {{Code|Map}} || Hash table (weak ref keys) || None || Yes || Yes || No || O(1) expected | |||
|- | |||
| {{Code|IdentityHashMap}} || {{Code|Map}} || Array (linear-probe, ref-equality) || None || Yes || Yes || No || O(1) expected | |||
|- | |||
| {{Code|EnumMap}} || {{Code|Map}} || Array (indexed by enum ordinal) || Enum declaration order || No || Yes || No || O(1) | |||
|} | |||
{{Code|TreeMap}} permits {{Code|null}} keys only if the {{Code|Comparator}} supports them; with natural ordering, a {{Code|NullPointerException}} is thrown. | |||
==See also== | |||
* [[Maps]] — main Maps page | |||
* [[Maps/ADT]] — Map Abstract Data Type specification | |||
* [[Maps/AbstractMap]] — AbstractMap implementation notes | |||
* [[Hash Maps]] — custom hash-table implementations | |||
* [[Java/Collections]] — overview of the Java Collections Framework | |||
=Flags= | =Flags= | ||
Latest revision as of 04:25, 8 June 2026
Notes
Maps are implemented in Java as part of the Java Collections Framework. Although maps do not extend the Template:Code interface, they are part of the overall Collections Framework.
Here is a link to the OpenJDK source code, Template:Code module:
- JDK 8: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/
- JDK 11+: https://github.com/openjdk/jdk/tree/master/src/java.base/share/classes/java/util
The Java Collections Framework provides a rich hierarchy of map interfaces and concrete implementations.
Interface hierarchy
The map-related interfaces form the following hierarchy:
| Interface | Description |
|---|---|
| Template:Code | The root interface. Defines the contract that all map implementations must satisfy. This is an interface, not an abstract class. |
| Template:Code | Extends Template:Code. A map whose keys are stored in sorted (ascending) order. Provides methods like Template:Code, Template:Code, Template:Code, Template:Code, and Template:Code. |
| Template:Code | Extends Template:Code. Adds navigation methods returning the closest matches for given search targets: Template:Code, Template:Code, Template:Code, Template:Code, as well as Template:Code and Template:Code. |
| Template:Code | Extends Template:Code. Adds thread-safe atomic operations such as Template:Code, Template:Code (key+value form), Template:Code, and Template:Code methods. |
| Template:Code | Extends both Template:Code and Template:Code. Provides a thread-safe navigable map. |
Map interface (the root)
Template:Code is the top-level contract for maps. It is an interface, not an abstract class. It declares all the fundamental map operations.
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/Map.java
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
Template:Code defines core methods including:
- Template:Code, Template:Code
- Template:Code, Template:Code, Template:Code
- Template:Code, Template:Code
- Template:Code, Template:Code, Template:Code
- Template:Code, Template:Code
Java 8 added default method implementations for functional-style operations:
- Template:Code
- Template:Code
- Template:Code and Template:Code
- Template:Code
- Template:Code
- Template:Code
- Template:Code
- Template:Code
- Template:Code
AbstractMap
Template:Code is an abstract class that implements the Template:Code interface. It provides skeletal implementations of most Template:Code operations, minimizing the effort required to create a concrete map implementation. Subclasses need only implement Template:Code to have a fully functioning (unmodifiable) map; implementing Template:Code as well yields a modifiable map.
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/AbstractMap.java
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/AbstractMap.html
Constructor (protected, for subclass use only):
public abstract class AbstractMap<K,V> implements Map<K,V> {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractMap() {
}
Template:Code method — iterates the entry set, handling null values safely:
public boolean containsValue(Object value) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (value==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getValue()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (value.equals(e.getValue()))
return true;
}
}
return false;
}
Template:Code method — uses an explicit Template:Code pointer to track the entry to delete, then calls the iterator's Template:Code:
public V remove(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
Entry<K,V> correctEntry = null;
if (key==null) {
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
correctEntry = e;
}
} else {
while (correctEntry==null && i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
correctEntry = e;
}
}
V oldValue = null;
if (correctEntry !=null) {
oldValue = correctEntry.getValue();
i.remove();
}
return oldValue;
}
Concrete implementations
HashMap
Template:Code is the standard general-purpose hash-table-based map implementation. It provides O(1) expected-time performance for Template:Code and Template:Code operations, assuming the hash function disperses keys properly among buckets.
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/HashMap.java
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html
Key characteristics:
- Extends Template:Code and implements Template:Code, Template:Code, Template:Code.
- Uses separate chaining with bins (linked lists). Starting in Java 8, when a bin accumulates enough collisions (Template:Code = 8), the bin is converted to a balanced tree (Template:Code), improving worst-case performance from O(n) to O(log n).
- Permits Template:Code keys and Template:Code values.
- Not synchronized. For a thread-safe counterpart, use Template:Code or Template:Code.
- Two configurable parameters affect performance: initial capacity (the number of buckets at creation) and load factor (the fraction of capacity at which the map is resized; default 0.75).
- The iterators returned by Template:Code, Template:Code, and Template:Code are fail-fast: if the map is structurally modified after an iterator is created (except through the iterator's own Template:Code method), the iterator throws Template:Code.
From the implementation comments describing the tree-bin transition:
* The use and transitions among plain vs tree modes is
* complicated by the existence of subclass LinkedHashMap. See
* below for hook methods defined to be invoked upon insertion,
* removal and access that allow LinkedHashMap internals to
* otherwise remain independent of these mechanics. (This also
* requires that a map instance be passed to some utility methods
* that may create new nodes.)
*
* The concurrent-programming-like SSA-based coding style helps
* avoid aliasing errors amid all of the twisty pointer operations.
TreeMap
Template:Code is a Red-Black tree-based implementation of the Template:Code interface. It stores keys in sorted (natural or Comparator-defined) order, yielding O(log n) time for Template:Code, Template:Code, Template:Code, Template:Code, and most other operations.
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/TreeMap.java
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html
Key characteristics:
- Extends Template:Code and implements Template:Code, Template:Code, Template:Code.
- Maintains keys in ascending sorted order, either by their natural ordering (Template:Code) or by a Template:Code supplied at construction time.
- Provides efficient access to min and max keys via Template:Code / Template:Code and Template:Code / Template:Code (both O(log n)).
- Template:Code methods like Template:Code, Template:Code, Template:Code, Template:Code allow range queries — each O(log n).
- Does not permit Template:Code keys (a Template:Code is thrown when a Template:Code key is used with natural ordering, or when the Template:Code does not allow Template:Code).
- Not synchronized.
- Slower than Template:Code for basic lookup/insertion (O(log n) vs. O(1) expected), but preferred when sorted traversal or range queries are needed.
LinkedHashMap
Template:Code extends Template:Code and maintains a doubly-linked list running through all entries. This preserves iteration order — either insertion order (default) or access order (configurable via constructor).
Source (JDK 8): http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/ff6c76f7733e/src/share/classes/java/util/LinkedHashMap.java
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html
Key characteristics:
- Extends Template:Code and implements Template:Code.
- Performance is slightly lower than Template:Code due to the overhead of maintaining the linked list, but iteration over the entry set is proportional to size (not capacity), unlike Template:Code.
- When constructed in access-order mode (Template:Code), it is suitable for building an LRU (least-recently-used) cache: override Template:Code to evict the oldest entry when the map exceeds a desired size.
- Not synchronized.
Class declaration:
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
{
The doubly-linked list is managed with Template:Code and Template:Code pointers (line 199 of the source):
/**
* The head (eldest) of the doubly linked list.
*/
transient LinkedHashMap.Entry<K,V> head;
/**
* The tail (youngest) of the doubly linked list.
*/
transient LinkedHashMap.Entry<K,V> tail;
Private utility method for linking a node at the end of the list (line 217):
// link at the end of list
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
LinkedHashMap.Entry<K,V> last = tail;
tail = p;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
}
Hashtable
Template:Code is a legacy hash-table-based map implementation that predates the Collections Framework. It was retrofitted to implement Template:Code when the Collections Framework was introduced in Java 1.2.
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/Hashtable.html
Key characteristics:
- Synchronized — all methods are thread-safe through intrinsic locking on the Template:Code instance. This makes it slower than Template:Code for single-threaded use.
- Does not permit Template:Code keys or Template:Code values (throws Template:Code).
- Largely superseded by Template:Code (non-synchronized) and Template:Code (for concurrent use). Template:Code is considered a legacy class; new code should prefer Template:Code or Template:Code.
ConcurrentHashMap
Template:Code is a highly concurrent, thread-safe hash-table-based map. Unlike Template:Code (which locks the entire map for every operation), Template:Code uses fine-grained locking (lock striping) to allow concurrent reads and a configurable number of concurrent writes.
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html
Key characteristics:
- Implements Template:Code and Template:Code.
- Does not permit Template:Code keys or Template:Code values.
- Obsoletes Template:Code for concurrent use cases. Provides dramatically better scalability under contention.
- Supports atomic compound operations: Template:Code, Template:Code, Template:Code.
- Iterators are weakly consistent: they reflect the state of the map at some point since the iterator was created, do not throw Template:Code, and may proceed concurrently with other operations.
- Bulk operations (Template:Code, Template:Code, Template:Code) support parallelism via the common Template:Code.
WeakHashMap
Template:Code is a hash-table-based map whose keys are held via weak references. When a key is no longer strongly reachable from elsewhere in the application, the garbage collector may reclaim it, and the corresponding entry is automatically removed from the map.
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/WeakHashMap.html
This is useful for canonicalizing or caching mappings where the lifetime of the entry should not prevent garbage collection of the key. Example use case: storing metadata about objects without preventing those objects from being garbage-collected.
IdentityHashMap
Template:Code is a hash-table-based map that uses reference equality (Template:Code) instead of object equality (Template:Code) when comparing keys. This violates the general Template:Code contract — it is intended for rare use cases where reference-equality semantics are required, such as topology-preserving object graphs, serialization, or proxy objects.
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/IdentityHashMap.html
EnumMap
Template:Code is a specialized map implementation for enum keys. Internally, it uses a compact array indexed by the enum's ordinal values, yielding extremely fast O(1) performance with minimal memory overhead.
Documentation: https://docs.oracle.com/javase/8/docs/api/java/util/EnumMap.html
Key characteristics:
- All keys in an Template:Code must belong to a single enum type, specified at construction time.
- Does not permit Template:Code keys; permits Template:Code values.
- Iteration order follows the natural order of the enum constants (the order in which they are declared).
- Extremely efficient: uses a plain Java array internally (one array slot per enum constant), avoiding hashing overhead entirely.
- Not synchronized.
Comparison of implementations
| Implementation | Interface | Underlying structure | Ordering | Template:Code keys | Template:Code values | Thread-safe | Typical Template:Code / Template:Code |
|---|---|---|---|---|---|---|---|
| Template:Code | Template:Code | Hash table (+ tree bins) | None | Yes | Yes | No | O(1) expected |
| Template:Code | Template:Code | Hash table + doubly-linked list | Insertion or access order | Yes | Yes | No | O(1) expected |
| Template:Code | Template:Code | Red-Black tree | Sorted (natural or Comparator) | No* | Yes | No | O(log n) |
| Template:Code | Template:Code | Hash table | None | No | No | Yes (per-method) | O(1) expected |
| Template:Code | Template:Code | Hash table (lock-striped) | None | No | No | Yes (non-blocking reads) | O(1) expected |
| Template:Code | Template:Code | Hash table (weak ref keys) | None | Yes | Yes | No | O(1) expected |
| Template:Code | Template:Code | Array (linear-probe, ref-equality) | None | Yes | Yes | No | O(1) expected |
| Template:Code | Template:Code | Array (indexed by enum ordinal) | Enum declaration order | No | Yes | No | O(1) |
Template:Code permits Template:Code keys only if the Template:Code supports them; with natural ordering, a Template:Code is thrown.
See also
- Maps — main Maps page
- Maps/ADT — Map Abstract Data Type specification
- Maps/AbstractMap — AbstractMap implementation notes
- Hash Maps — custom hash-table implementations
- Java/Collections — overview of the Java Collections Framework
Flags
| Maps and Dictionaries Part of Computer Science Notes
Series on Data Structures
Maps/Dictionaries Maps · Maps/ADT · Maps in Java · Maps/OOP · Maps/Operations and Performance Map implementations: Maps/AbstractMap · Maps/UnsortedArrayMap · Maps/SortedArrayMap Dictionary implementations: Dictionaries/LinkedDict · Dictionaries/ArrayDict
Hashes Hash Maps/OOP · Hash Maps/Operations and Performance Hash Maps/Dynamic Resizing · Hash Maps/Collision Handling with Chaining Hash functions: Hash Functions · Hash Functions/Cyclic Permutation Hash map implementations: Hash Maps/AbstractHashMap · Hash Maps/ChainedHashMap
Skip Lists · Java/ConcurrentSkipList · Java implementations: SkipList
Sets Sets · Sets/ADT · Sets in Java · Sets/OOP · Multisets
|