Ένα HashMap είναι ένας περιέκτης που μπορεί να χρησιμοποιηθεί για την αποθήκευση ζευγών κλειδιού-τιμής. Σε άλλες γλώσσες προγραμματισμού, αυτή η δομή δεδομένων ονομάζεται μερικές φορές συσχετιστικός πίνακας ή πίνακας κατακερματισμού. Ο χάρτης περιέχει ένα σύνολο κλειδιών, καθένα από τα οποία αντιστοιχίζεται σε μια συγκεκριμένη τιμή. Ο χρήστης μπορεί να ανακτήσει μια αποθηκευμένη τιμή περνώντας το κατάλληλο κλειδί. Οι χρήστες μπορούν επίσης να εισάγουν και να διαγράψουν κλειδιά και τις σχετιζόμενες τιμές.
Το HashMap είναι μια γενική συλλογή (όπως τα περισσότερα collections της standard library) και έτσι υποστηρίζει μεγάλη ποικιλία τύπων ως κλειδιά, συμπεριλαμβανομένων δομών struct που ορίζει ο χρήστης και πλειάδων. Οι τιμές του μπορούν να είναι οποιουδήποτε τύπου.
HashMap
Δημιουργείς ένα HashMap χρησιμοποιώντας τη συνάρτηση HashMap::new(). Το παρακάτω απόσπασμα κώδικα δημιουργεί ένα HashMap με ονόματα ομάδων αντιστοιχισμένα σε σκορ.
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
HashMap
Αν ξέρεις ότι μια τιμή υπάρχει μέσα σε ένα HashMap, τότε είναι κατάλληλο να χρησιμοποιήσεις τον τελεστή ευρετηρίασης ([]). Για να ανακτήσουμε το σκορ της μπλε ομάδας, για παράδειγμα, μπορούμε να χρησιμοποιήσουμε το scores["Blue"]. Ωστόσο, αν το κατάλληλο ζεύγος κλειδιού-τιμής δεν υπάρχει μέσα στο hashmap, αυτή η πράξη θα προκαλέσει panic.
Εκτός από τον τελεστή ευρετηρίασης, υπάρχουν δύο ακόμη τρόποι για να προσπελάσεις τιμές που είναι αποθηκευμένες σε ένα HashMap. Ο πρώτος είναι να χρησιμοποιήσεις τη συνάρτηση μέλους get:
if let Some(blue_score) = scores.get("Blue") {
println!("Blue scored: {blue_score} \n");
}
Η get προσπελαύνει την τιμή που είναι αποθηκευμένη για το κλειδί που ζητάς. Επιστρέφει None αν το κλειδί που έδωσες δεν υπάρχει στο HashMap, και Some(value) αν το κλειδί υπάρχει. Για περισσότερα σχετικά με τα Options στη Rust, δες την έννοια Options.
Ο άλλος τρόπος για να προσπελάσεις τιμές που είναι αποθηκευμένες σε ένα HashMap είναι να χρησιμοποιήσεις τη μέθοδο entry. Η μέθοδος entry (ή το entry API) επιστρέφει μια αναφορά στην καταχώριση του ζεύγους κλειδιού-τιμής στο HashMap. Η καταχώριση αντιπροσωπεύει την κατάσταση αυτού του κλειδιού στον χάρτη. Αν το κλειδί δεν υπάρχει, τότε δεν υπάρχει τιμή στην καταχώριση (και επιτρέπει να εισαχθεί μία).
let mut vote_counter: HashMap<_, usize> = HashMap::new();
let votes = ["Blue", "Red", "Red", "Blue", "Red", "Blue", "Blue"];
for vote in votes {
let count = vote_counter.entry(vote).or_default();
*count += 1;
}
println!("{vote_counter:#?}");
Αυτό το API κάνει ορισμένα κοινά μοτίβα πρόσβασης πολύ βολικά· υπάρχει μια ολόκληρη έννοια (Entry API) αφιερωμένη σε αυτό.
Τα HashMap είναι σχετικά γρήγορα και έχουν αποσβεσμένη σταθερή πολυπλοκότητα χρόνου (O(1)) για όλες τις πράξεις που αφορούν ένα μόνο κλειδί.
Το HashMap είναι μια γενική δομή δεδομένων, που σημαίνει ότι υποστηρίζει αυθαίρετους τύπους ως κλειδιά και τιμές, με έναν μόνο περιορισμό: για να χρησιμοποιηθεί ένας τύπος ως τύπος κλειδιού, πρέπει να έχει υλοποίηση για δύο traits: τα Eq και Hash. Δεν υπάρχουν όρια traits για τον τύπο της τιμής.