From charlesreid1

(Overhaul: add introduction, organize operations into clear categories with tables, fix typos, expand Java section with full interface, add expected complexity table, add See also links. (via update-page on MediaWiki MCP Server))
(Add Python mapping protocol section alongside the existing Java Map interface section (via update-page on MediaWiki MCP Server))
 
Line 126: Line 126:


Standard implementations: <code>HashMap</code> (hash table, O(1) expected), <code>TreeMap</code> (red-black tree, O(log n)), <code>LinkedHashMap</code> (hash table with insertion-order iteration).
Standard implementations: <code>HashMap</code> (hash table, O(1) expected), <code>TreeMap</code> (red-black tree, O(log n)), <code>LinkedHashMap</code> (hash table with insertion-order iteration).
==Python mapping protocol==
Python specifies the map ADT through two abstract base classes in <code>[https://docs.python.org/3/library/collections.abc.html collections.abc]</code>: the read-only <code>Mapping</code> and the mutable <code>MutableMapping</code> (which extends <code>Mapping</code>). The built-in <code>dict</code> type is the primary concrete implementation; user-defined map types can register as virtual subclasses or inherit directly from these ABCs.
The ABC hierarchy relevant to maps:
* <code>Container</code> → <code>Collection</code> → <code>Mapping</code> → <code>MutableMapping</code>
* <code>Iterable</code> → <code>Collection</code>
* <code>Sized</code> → <code>Collection</code>
A minimal concrete <code>MutableMapping</code> must implement five abstract methods: <code>__getitem__</code>, <code>__setitem__</code>, <code>__delitem__</code>, <code>__iter__</code>, and <code>__len__</code>. All other mixin methods are derived from these five.
===Core methods — <code>Mapping</code> (read-only)===
{| class="wikitable"
|-
! Method !! Description
|-
| <code>m[k]</code> (<code>__getitem__</code>) || Return the value for key <code>k</code>; raise <code>KeyError</code> if absent. ''Abstract.''
|-
| <code>k '''in''' m</code> (<code>__contains__</code>) || Return <code>True</code> if key <code>k</code> is present. Default: iterate and compare.
|-
| <code>len(m)</code> (<code>__len__</code>) || Return the number of key-value pairs. ''Abstract.''
|-
| <code>iter(m)</code> (<code>__iter__</code>) || Return an iterator over the keys. ''Abstract.''
|-
| <code>m.keys()</code> || Return a <code>KeysView</code> (set-like) of all keys.
|-
| <code>m.values()</code> || Return a <code>ValuesView</code> of all values.
|-
| <code>m.items()</code> || Return an <code>ItemsView</code> (set-like) of <code>(k, v)</code> tuples.
|-
| <code>m.get(k, d=None)</code> || Return <code>m[k]</code> if key exists; otherwise return default <code>d</code>.
|-
| <code>m == m2</code> (<code>__eq__</code>) || Return <code>True</code> if both maps have the same key-value pairs.
|}
All views are live: they reflect changes to the underlying map.
===Mutable methods — <code>MutableMapping</code>===
{| class="wikitable"
|-
! Method !! Description
|-
| <code>m[k] = v</code> (<code>__setitem__</code>) || Insert or overwrite the mapping for key <code>k</code>. ''Abstract.''
|-
| <code>del m[k]</code> (<code>__delitem__</code>) || Remove the mapping for key <code>k</code>; raise <code>KeyError</code> if absent. ''Abstract.''
|-
| <code>m.pop(k, d)</code> || Remove key <code>k</code> and return its value; return <code>d</code> (or raise <code>KeyError</code>) if absent.
|-
| <code>m.popitem()</code> || Remove and return an arbitrary <code>(k, v)</code> pair; raise <code>KeyError</code> if empty.
|-
| <code>m.setdefault(k, d=None)</code> || Return <code>m[k]</code> if present; otherwise set <code>m[k] = d</code> and return <code>d</code>.
|-
| <code>m.clear()</code> || Remove all key-value pairs.
|-
| <code>m.update(m2)</code> || For every <code>(k, v)</code> in <code>m2</code> (or from keyword arguments), set <code>m[k] = v</code>.
|}
===Dict-specific methods===
Beyond the <code>MutableMapping</code> contract, <code>dict</code> provides:
{| class="wikitable"
|-
! Method !! Description
|-
| <code>dict.fromkeys(iterable, v=None)</code> || Class method: build a new dict with keys from an iterable, all mapped to value <code>v</code>.
|-
| <code>m.copy()</code> || Return a shallow copy of the dict.
|-
| <code>m {{!}} m2</code> (<code>__or__</code>) || Return a new dict merging <code>m</code> and <code>m2</code>. (Python 3.9+)
|-
| <code>m {{!}}= m2</code> (<code>__ior__</code>) || In-place merge: update <code>m</code> with <code>m2</code>. (Python 3.9+)
|-
| <code>reversed(m)</code> (<code>__reversed__</code>) || Return a reverse iterator over keys. (Python 3.8+)
|}
===Standard implementations===
{| class="wikitable"
|-
! Class !! Module !! Backing !! Notes
|-
| <code>dict</code> || built-in || Hash table, O(1) expected || The default mapping type. Insertion-ordered since Python 3.7.
|-
| <code>OrderedDict</code> || <code>collections</code> || Doubly-linked list + hash table || Remembers insertion order (present since Python 3.1; <code>dict</code> also preserves order since 3.7, but <code>OrderedDict</code> adds <code>move_to_end</code> and order-sensitive equality).
|-
| <code>defaultdict</code> || <code>collections</code> || Hash table || Missing keys are auto-created by a user-supplied factory function.
|-
| <code>Counter</code> || <code>collections</code> || Hash table || Multiset: keys map to integer counts. Supports <code>+</code>, <code>-</code>, <code>&amp;</code>, <code>|</code> operators.
|-
| <code>ChainMap</code> || <code>collections</code> || Linked list of mappings || Chains multiple mappings together; lookups search each in order.
|-
| <code>MappingProxyType</code> || <code>types</code> || Wraps a dict || Read-only dynamic view onto another mapping.
|}
Python has no balanced-BST map in the standard library. Third-party packages such as [https://grantjenks.com/docs/sortedcontainers/ sortedcontainers] provide <code>SortedDict</code> with O(log n) operations.
===Example: minimal custom <code>MutableMapping</code>===
<syntaxhighlight lang="python">
from collections.abc import MutableMapping
class SingleEntryMap(MutableMapping):
    """A map that holds at most one key-value pair."""
    def __init__(self):
        self._key = None
        self._value = None
    def __getitem__(self, key):
        if self._key == key:
            return self._value
        raise KeyError(key)
    def __setitem__(self, key, value):
        self._key = key
        self._value = value
    def __delitem__(self, key):
        if self._key == key:
            self._key = None
            self._value = None
        else:
            raise KeyError(key)
    def __iter__(self):
        if self._key is not None:
            yield self._key
    def __len__(self):
        return 1 if self._key is not None else 0
    def __repr__(self):
        return repr(dict(self)) if self._key is not None else '{}'
</syntaxhighlight>
Implementing the five abstract methods automatically provides <code>keys()</code>, <code>values()</code>, <code>items()</code>, <code>get()</code>, <code>pop()</code>, <code>popitem()</code>, <code>setdefault()</code>, <code>clear()</code>, <code>update()</code>, <code>__contains__</code>, and <code>__eq__</code> — all supplied by the <code>MutableMapping</code> mixin.


==See also==
==See also==

Latest revision as of 04:12, 8 June 2026

The Map Abstract Data Type (ADT) defines the interface contract that all map implementations must satisfy. It specifies what operations a map supports without prescribing how they are implemented — the hallmark of an ADT. A concrete map implementation may use a hash table, a balanced tree, a sorted array, or any other suitable data structure.

A map stores key-value pairs. Each key maps to exactly one value (the map is a function from a domain of keys to a codomain of values). Keys must be unique; distinct keys may map to the same value.

Basic operations

These five operations constitute the essential interface of any map ADT:

Operation Pseudocode signatures Description
get m[k], m.get(k) Return the value associated with key k; raise a key error if k is absent.
set m[k] = v, m.put(k, v) Associate value v with key k, overwriting any previous mapping.
remove del m[k], m.remove(k) Remove the entry for key k; raise a key error if absent.
size len(m), m.size() Return the number of key-value pairs in the map.
iterate iter(m) Return an iterator over the keys of the map.

Convenience operations

These operations can each be expressed in terms of the basic five above, but are provided for programmer convenience.

Lookup

  • m.contains(k) / k in m — test whether key k exists in the map; returns boolean
  • m.get(k, d) — return m[k] if key k exists; otherwise return default value d
  • m.setdefault(k, d) — if key k exists return m[k]; otherwise set m[k] = d and return d

Modification

  • m.pop(k, d) — remove key k and return its associated value; return d if key is absent
  • m.popitem() — remove and return an arbitrary (k, v) pair; raise a key error if the map is empty
  • m.clear() — remove all key-value pairs from the map

Views

  • m.keys() — return a set-like view of all keys
  • m.values() — return a set-like view of all values
  • m.items() — return a set-like view of all (k, v) tuples

Views are live: changes to the underlying map are reflected in the view, and vice versa.

Bulk operations

  • m.update(m2) — for every (k, v) pair in map m2, set m[k] = v
  • m.equals(m2) — return true if the two maps contain the same key-value pairs

Expected complexity

While the ADT itself is implementation-agnostic, useful map implementations achieve the following amortized bounds:

Implementation get put remove contains
Hash table O(1) O(1) O(1) O(1)
Balanced BST O(log n) O(log n) O(log n) O(log n)
Unsorted array O(n) O(n) O(n) O(n)
Sorted array O(log n) O(n) O(n) O(log n)

Java Map interface

The Java Collections Framework specifies the map ADT through the java.util.Map<K,V> interface.

Core methods

Method Description
size() Return the number of key-value mappings.
isEmpty() Return true if the map contains no mappings.
get(Object key) Return the value to which key is mapped, or null if absent.
put(K key, V value) Associate value with key; return the previous value, or null.
remove(Object key) Remove the mapping for key; return the previous value, or null.
containsKey(Object key) Return true if the map contains key.
containsValue(Object value) Return true if the map maps one or more keys to value.
keySet() Return a Set<K> view of the keys.
values() Return a Collection<V> view of the values.
entrySet() Return a Set<Map.Entry<K,V>> view of the entries.

Bulk and default methods

Method Description
putAll(Map m) Copy all mappings from m into this map.
clear() Remove all mappings.
getOrDefault(Object key, V def) Return value for key, or def if absent. (Java 8)
putIfAbsent(K key, V value) Insert only if key is not already present. (Java 8)
replace(K key, V old, V new) Replace value only if currently mapped to old. (Java 8)
computeIfAbsent(K key, Function f) If key is absent, compute and insert a value via f. (Java 8)
merge(K key, V val, BiFunction remap) Merge val with existing value using remap. (Java 8)

Standard implementations: HashMap (hash table, O(1) expected), TreeMap (red-black tree, O(log n)), LinkedHashMap (hash table with insertion-order iteration).

Python mapping protocol

Python specifies the map ADT through two abstract base classes in collections.abc: the read-only Mapping and the mutable MutableMapping (which extends Mapping). The built-in dict type is the primary concrete implementation; user-defined map types can register as virtual subclasses or inherit directly from these ABCs.

The ABC hierarchy relevant to maps:

  • ContainerCollectionMappingMutableMapping
  • IterableCollection
  • SizedCollection

A minimal concrete MutableMapping must implement five abstract methods: __getitem__, __setitem__, __delitem__, __iter__, and __len__. All other mixin methods are derived from these five.

Core methods — Mapping (read-only)

Method Description
m[k] (__getitem__) Return the value for key k; raise KeyError if absent. Abstract.
k in m (__contains__) Return True if key k is present. Default: iterate and compare.
len(m) (__len__) Return the number of key-value pairs. Abstract.
iter(m) (__iter__) Return an iterator over the keys. Abstract.
m.keys() Return a KeysView (set-like) of all keys.
m.values() Return a ValuesView of all values.
m.items() Return an ItemsView (set-like) of (k, v) tuples.
m.get(k, d=None) Return m[k] if key exists; otherwise return default d.
m == m2 (__eq__) Return True if both maps have the same key-value pairs.

All views are live: they reflect changes to the underlying map.

Mutable methods — MutableMapping

Method Description
m[k] = v (__setitem__) Insert or overwrite the mapping for key k. Abstract.
del m[k] (__delitem__) Remove the mapping for key k; raise KeyError if absent. Abstract.
m.pop(k, d) Remove key k and return its value; return d (or raise KeyError) if absent.
m.popitem() Remove and return an arbitrary (k, v) pair; raise KeyError if empty.
m.setdefault(k, d=None) Return m[k] if present; otherwise set m[k] = d and return d.
m.clear() Remove all key-value pairs.
m.update(m2) For every (k, v) in m2 (or from keyword arguments), set m[k] = v.

Dict-specific methods

Beyond the MutableMapping contract, dict provides:

Method Description
dict.fromkeys(iterable, v=None) Class method: build a new dict with keys from an iterable, all mapped to value v.
m.copy() Return a shallow copy of the dict.
m2 (__or__) Return a new dict merging m and m2. (Python 3.9+)
= m2 (__ior__) In-place merge: update m with m2. (Python 3.9+)
reversed(m) (__reversed__) Return a reverse iterator over keys. (Python 3.8+)

Standard implementations

Class Module Backing Notes
dict built-in Hash table, O(1) expected The default mapping type. Insertion-ordered since Python 3.7.
OrderedDict collections Doubly-linked list + hash table Remembers insertion order (present since Python 3.1; dict also preserves order since 3.7, but OrderedDict adds move_to_end and order-sensitive equality).
defaultdict collections Hash table Missing keys are auto-created by a user-supplied factory function.
Counter collections Hash table operators.
ChainMap collections Linked list of mappings Chains multiple mappings together; lookups search each in order.
MappingProxyType types Wraps a dict Read-only dynamic view onto another mapping.

Python has no balanced-BST map in the standard library. Third-party packages such as sortedcontainers provide SortedDict with O(log n) operations.

Example: minimal custom MutableMapping

from collections.abc import MutableMapping

class SingleEntryMap(MutableMapping):
    """A map that holds at most one key-value pair."""

    def __init__(self):
        self._key = None
        self._value = None

    def __getitem__(self, key):
        if self._key == key:
            return self._value
        raise KeyError(key)

    def __setitem__(self, key, value):
        self._key = key
        self._value = value

    def __delitem__(self, key):
        if self._key == key:
            self._key = None
            self._value = None
        else:
            raise KeyError(key)

    def __iter__(self):
        if self._key is not None:
            yield self._key

    def __len__(self):
        return 1 if self._key is not None else 0

    def __repr__(self):
        return repr(dict(self)) if self._key is not None else '{}'

Implementing the five abstract methods automatically provides keys(), values(), items(), get(), pop(), popitem(), setdefault(), clear(), update(), __contains__, and __eq__ — all supplied by the MutableMapping mixin.

See also