HashMap[K, V] — хеш-таблица Nova: открытая адресация с линейным пробированием, автоматическое увеличение при достижении load_factor (по умолчанию 0.75). Тип ключа обязан удовлетворять Hashable — структурному протоколу, требующему метод hash() -> u64. Встроенные типы (str, int, …) удовлетворяют Hashable по умолчанию.

Синтаксис map-literal ["key": value, ...] (D108) разворачивается в HashMap, а литерал записи {field: val} приводится к HashMap[str, V] (D55).

mut m = HashMap[str, int].new()
m.insert("alice", 1)
m.insert("bob", 2)
assert(m.get("alice") == Some(1))
assert(m.len() == 2)

for (k, v) in m.iter() {
    assert(v > 0)
}

HashMap

стабильно с 0.1
type HashMap[K Hashable, V] { ... }

Хеш-таблица с открытой адресацией и линейным пробированием. Параметр типа K обязан удовлетворять Hashable. Растёт автоматически, когда число записей превышает capacity * load_factor.


Hashable

стабильно с 0.1
type Hashable protocol {
    fn hash() -> u64
}

Структурный протокол: любой тип с методом hash() -> u64 удовлетворяет Hashable. Используется как ограничение для K в HashMap[K Hashable, V]. Встроенные типы (str, int, bool, …) реализуют его через prelude.


new

стабильно с 0.1
fn HashMap.new() -> HashMap[K, V]

Создаёт пустой HashMap с начальной ёмкостью 16.

Примеры

mut m = HashMap[str, int].new()
assert(m.is_empty())

with_capacity

стабильно с 0.1
fn HashMap.with_capacity(min_capacity int) -> HashMap[K, V]

Создаёт пустой HashMap, вмещающий не менее min_capacity записей без рехеширования. Аргумент — это число записей, а не число бакетов. Используйте, когда конечный размер известен заранее.

Примеры

mut m = HashMap[str, int].with_capacity(100)
for i in 0..100 { m.insert("k" + i.to_str(), i) }
assert(m.len() == 100)

from

стабильно с 0.1
fn HashMap.from(pairs [](K, V)) -> Self

Строит HashMap из массива пар (key, value). При дублировании ключей побеждает последняя запись.

Примеры

ro m = HashMap[str, int].from([("a", 1), ("b", 2)])
assert(m.get("a") == Some(1))
assert(m.len() == 2)

get

стабильно с 0.1
fn HashMap @get(key K) -> Option[V]

Ищет key. Возвращает Some(value), если найден, иначе None.

Примеры

mut m = HashMap[str, int].new()
m.insert("x", 10)
assert(m.get("x") == Some(10))
assert(m.get("y") == None)

contains

стабильно с 0.1
fn HashMap @contains(key K) -> bool

Проверяет наличие key без извлечения значения. Эквивалентно m.get(key) != None, но не требует построения Option.


get_or_insert

стабильно с 0.1
fn HashMap mut @get_or_insert(key K, fallback fn() -> V) -> V

Возвращает значение для key, если оно существует. Иначе вызывает fallback(), вставляет результат и возвращает его. Fallback ленив — вызывается только при промахе кеша.

Примеры

mut counts = HashMap[str, int].new()
ro prev = counts.get_or_insert("foo", || 0)
counts.insert("foo", prev + 1)
assert(counts.get("foo") == Some(1))

insert

стабильно с 0.1
fn HashMap mut @insert(key K, value V) -> Option[V]

Вставляет (key, value). Если ключ уже существует, перезаписывает его и возвращает Some(old_value). Иначе вставляет и возвращает None. Может вызвать рехеширование.

Примеры

mut m = HashMap[str, int].new()
assert(m.insert("a", 1) == None)
assert(m.insert("a", 2) == Some(1))
assert(m.get("a") == Some(2))

remove

стабильно с 0.1
fn HashMap mut @remove(key K) -> Option[V]

Удаляет запись для key. Возвращает Some(old_value), если ключ существовал, иначе None. Оставляет tombstone-слот — внутренний массив не сжимается.

Примеры

mut m = HashMap[str, int].from([("a", 1)])
assert(m.remove("a") == Some(1))
assert(m.remove("a") == None)

clear

стабильно с 0.1
fn HashMap mut @clear() -> ()

Удаляет все записи. Внутренний массив бакетов сохраняется (ёмкость не теряется), поэтому повторная вставка элементов не требует немедленного перевыделения памяти.


merge_from

стабильно с 0.1
fn HashMap mut @merge_from(other HashMap[K, V]) -> ()

Сливает все записи из other в self. Семантика перезаписи: существующие ключи перезаписываются.

Примеры

mut a = HashMap[str, int].from([("x", 1)])
ro b = HashMap[str, int].from([("x", 99), ("y", 2)])
a.merge_from(b)
assert(a.get("x") == Some(99))
assert(a.get("y") == Some(2))

len

стабильно с 0.1
fn HashMap @len() -> int

Число живых записей (не учитывает tombstone-слоты, оставленные remove).


is_empty

стабильно с 0.1
fn HashMap @is_empty() -> bool

Возвращает true, когда len() == 0.


capacity

стабильно с 0.1
fn HashMap @capacity() -> int

Полный размер внутреннего массива бакетов. Всегда ≥ len(). Используйте with_capacity, чтобы задать его при создании.


iter

стабильно с 0.1
fn HashMap @iter() -> HashMapIter[K, V]

Итератор по парам (key, value) в неопределённом порядке.

Примеры

ro m = HashMap[str, int].from([("a", 1), ("b", 2)])
for (k, v) in m.iter() {
    assert(v > 0)
}

keys

стабильно с 0.1
fn HashMap @keys() -> KeysIter[K, V]

Итератор только по ключам, в неопределённом порядке.


values

стабильно с 0.1
fn HashMap @values() -> ValuesIter[K, V]

Итератор только по значениям, в неопределённом порядке.


filter

стабильно с 0.1
fn HashMap @filter(pred fn(K, V) -> bool) -> HashMap[K, V]

Возвращает новый HashMap, содержащий только пары, для которых pred(k, v) равен true. Исходный не изменяется.

Примеры

ro m = HashMap[str, int].from([("a", 1), ("b", 2), ("c", 3)])
ro big = m.filter(|_, v| v > 1)
assert(big.len() == 2)

clone

стабильно с 0.1
fn HashMap @clone() -> HashMap[K, V]

Создаёт независимую глубокую копию таблицы. Изменения копии не влияют на оригинал.

Примеры

ro m = HashMap[str, int].from([("a", 1)])
ro m2 = m.clone()
assert(m2.get("a") == Some(1))