Это изменяемая структура словарь (“dictionary” в Python), которая хранит пары “ключ->значение”. В Rust Prelude она не входит, макроса создания не имеет. Поэтому нужно указывать библиотеку явно и явно создавать структуру.
scores.insert(String::from("Gamma"),3);// вставка дважды значений по одному
scores.insert(String::from("Gamma"),6);// ключу сохранит последнее значение
Записывать значение, если у ключа его нет:
scores.entry(String::from("Delta")).or_insert(4);// entry проверяет наличие
// значения, or_insert возвращает mut ссылку на него, либо записывает новое
// значение и возвращает mut ссылку на это значение.
Записывать значение, если ключа нет. Если же у ключа есть значение, модифицировать его:
usestd::collections::HashMap;letmutmap: HashMap<&str,u32>=HashMap::new();map.entry("poneyland")// первое добавление
.and_modify(|e|{*e+=1}).or_insert(42);// добавит ключ "poneyland: 42"
assert_eq!(map["poneyland"],42);map.entry("poneyland")// второе добавление найдёт ключ со значением
.and_modify(|e|{*e+=1})// и модифицирует его
.or_insert(42);assert_eq!(map["poneyland"],43);
Записывать значение, если ключа нет, в виде результата функции. Эта функция получает ссылку на значение ключа key, который передаётся в .entry(key):
Упорядоченная по ключам K структура данных на основе B-дерева.
Ключевые отличия от HashMap:
Свойство
HashMap
BTreeMap
Внутренняя структура
Хэш таблица
Дерево поиска
Упорядоченность
Не гарантированная
Ключи всегда упорядочены
Скорость
O(1)
O(log n)
Требования
Hash + Eq
Ord
Потребление памяти
Выше
Ниже
Применение
Когда нужно сразу сортировать данные:
letmutscores=BTreeMap::new();scores.insert("Charlie",85);scores.insert("Alice",92);scores.insert("Bob",78);// Итерация сразу в отсортированном порядке по ключам
for(name,score)in&scores{println!("{}: {}",name,score);// Alice, Bob, Charlie
}// Получить 1ый и последний элементы
println!("{:?}",scores.first_key_value());// ("Alice", 92)
println!("{:?}",scores.last_key_value());// ("Charlie", 85)
Работа с диапазонами значений:
// Диапазоны заданы кортежами (нижняя_граница, верхняя_граница)
letmutprice_ranges=BTreeMap::new();price_ranges.insert((0,10),"Budget");price_ranges.insert((11,50),"Standard");price_ranges.insert((51,100),"Premium");price_ranges.insert((101,1000),"Luxury");letquery_price=42;// Поиск по диапазонам (линейный в данном случае)
for((low,high),category)in&price_ranges{ifquery_price>=*low&&query_price<=*high{println!("Price ${} is in category: {} (range: {}-{})",query_price,category,low,high);break;}}
useserde_jsonletmutconfig=BTreeMap::new();config.insert("zebra","animal");config.insert("apple","fruit");config.insert("banana","fruit");// сериализация в JSON с порядком элементов
letjson=serde_json::to_string_pretty(&config).unwrap();println!("{}",json);// ключи будут в порядке: apple, banana, zebra
Для небольших коллекций (< 1000 элементов) или когда требуется отсортированный порядок, BTreeMap часто предпочтительнее. Для больших коллекций, где нужна максимальная скорость, а порядок не имеет значения, HashMap обычно лучше.