BTreeMap în Rust

Dicționar cu cheile mereu sortate: aceleași operații ca HashMap, dar parcurgerea și afișarea sunt în ordinea cheilor.

Sintaxă
use std::collections::BTreeMap;

let mut m: BTreeMap<K, V> = BTreeMap::new();
pub fn insert(&mut self, key: K, value: V) -> Option<V>
pub fn get<Q>(&self, key: &Q) -> Option<&V>
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>

Ce face BTreeMap

BTreeMap<K, V> ține perechile cheie-valoare într-un arbore echilibrat, ordonat după cheie. insert, get, remove, entry, len, iter merg exact ca la HashMap (inclusiv insert care returnează valoarea veche și get care returnează Option).

Diferența: ordinea este garantată. {:?}, for, keys() și values() dau cheile crescător, la fiecare rulare. În plus, poți cere un interval de chei (range) sau cea mai mică/mare cheie (first_key_value, last_key_value).

Cheile trebuie să implementeze Ord (nu Hash). Operațiile sunt puțin mai lente decât la HashMap pentru colecții mari, dar pentru afișări, rapoarte și date mici diferența nu contează. Alege BTreeMap când ai nevoie de ordine sau de intervale.

Parametri

Parametru Descriere
key Cheia: la insert prin valoare, la get/remove prin referință.
value Valoarea asociată (la insert).

Ce returnează

insert: Option<V> (valoarea veche). get: Option<&V>. remove: Option<V>.

Exemple

Exemplul 1: Catalogul, mereu în ordine alfabetică

use std::collections::BTreeMap;

fn main() {
    let mut note = BTreeMap::new();
    note.insert("Mihai", 8);
    note.insert("Ana", 10);
    note.insert("Ioana", 9);
    note.insert("Radu", 7);
    println!("{:?}", note);

    println!("nota Ioanei: {:?}", note.get("Ioana"));
    println!("remove Radu: {:?}", note.remove("Radu"));
    println!("insert Ana 9: {:?}", note.insert("Ana", 9));
    for (nume, nota) in &note {
        println!("{nume}: {nota}");
    }
}

Rezultat

{"Ana": 10, "Ioana": 9, "Mihai": 8, "Radu": 7}
nota Ioanei: Some(9)
remove Radu: Some(7)
insert Ana 9: Some(10)
Ana: 9
Ioana: 9
Mihai: 8

Exemplul 2: Momente din istoria României, în ordine cronologică

Cheile sunt anii; ordinea inserării nu contează.

use std::collections::BTreeMap;

fn main() {
    let mut evenimente = BTreeMap::new();
    evenimente.insert(1918, "Marea Unire");
    evenimente.insert(1859, "Unirea Principatelor");
    evenimente.insert(2007, "aderarea la Uniunea Europeană");
    evenimente.insert(1989, "Revoluția");
    evenimente.insert(1877, "Independența");
    for (an, ce) in &evenimente {
        println!("{an}: {ce}");
    }
}

Rezultat

1859: Unirea Principatelor
1877: Independența
1918: Marea Unire
1989: Revoluția
2007: aderarea la Uniunea Europeană

Exemplul 3: Frecvența literelor, sortată automat

use std::collections::BTreeMap;

fn main() {
    let mut litere: BTreeMap<char, u32> = BTreeMap::new();
    for c in "Constanța".to_lowercase().chars() {
        *litere.entry(c).or_insert(0) += 1;
    }
    let text: Vec<String> = litere.iter().map(|(c, n)| format!("{c}={n}")).collect();
    println!("{}", text.join(" "));
}

Rezultat

a=2 c=1 n=2 o=1 s=1 t=1 ț=1

Greșeli frecvente

  • Te aștepți la ordinea inserării. BTreeMap sortează după cheie; pentru ordinea inserării ține un Vec de perechi.
  • Chei de tip f64: the trait bound `f64: Ord` is not satisfied. Folosește întregi sau un tip propriu care implementează Ord.
  • Folosești BTreeMap doar pentru viteză pe colecții foarte mari, unde nu contează ordinea. HashMap este de obicei mai rapid.

Comenzi înrudite

  • BTreeMap::range: Parcurge doar perechile cu cheile într-un interval (a..b, a..=b, a.., ..b), în ordine crescătoare.
  • BTreeMap::first_key_value: Returnează perechea cu cea mai mică cheie (first) sau cu cea mai mare cheie (last); None dacă dicționarul e gol.
  • HashMap: Dicționarul din Rust: asociază fiecărei chei o valoare și o găsește foarte repede după cheie. Ordinea nu este garantată.
  • HashMap::entry: Caută o cheie o singură dată și îți dă „locul” ei (Entry), ca să inserezi, să citești sau să modifici fără o a doua căutare.
  • BTreeSet: Mulțime cu elementele mereu sortate: fără duplicate, ca HashSet, dar parcurgerea este în ordine crescătoare.