পাঠ ৮.৩

Hash Map-এ key এবং value রাখা

Storing Keys with Associated Values in Hash Maps

HashMap<K, V> key-value pair রাখে — hashing function ব্যবহার করে। Vector-এ index দিয়ে access, hash map-এ key দিয়ে। অন্য language-এ এটা dictionary, map, hash, বা object।

তৈরি ও insert

HashMap prelude-এ নেই — explicitly import:

use std::collections::HashMap;

let mut scores = HashMap::new();

scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

Vector-এর মতো heap-এ থাকে, homogeneous — সব key এক type, সব value এক type।

Value access — get

use std::collections::HashMap;

let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

let team_name = String::from("Blue");
let score = scores.get(&team_name).copied().unwrap_or(0);

.get() Option<&V> return করে — key না থাকলে None.copied() Option<&i32>-কে Option<i32>-এ convert করে; .unwrap_or(0) None হলে 0 দেয়।

Iterate

for (key, value) in &scores {
    println!("{key}: {value}");
}

Order arbitrary — প্রতিবার চালালে আলাদা হতে পারে।

Ownership

Copy type (i32 ইত্যাদি) — value copy। Owned type (String) — move:

use std::collections::HashMap;

let field_name = String::from("Favorite color");
let field_value = String::from("Blue");

let mut map = HashMap::new();
map.insert(field_name, field_value);
// field_name and field_value are invalid at this point

Insert-এর পর map-ই owner; original variable use করা যাবে না।

Update — তিন strategy

১. Overwrite

use std::collections::HashMap;

let mut scores = HashMap::new();

scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);

println!("{scores:?}"); // {"Blue": 25}

একই key-এ দ্বিতীয়বার insert পুরোনো value replace করে।

২. Insert only-if-absent — entry API

use std::collections::HashMap;

let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);

scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);

println!("{scores:?}"); // {"Yellow": 50, "Blue": 10}

.entry(key).or_insert(value) — key-এর জন্য entry-র mutable reference return করে। Key থাকলে existing value-র reference, না থাকলে value insert করে নতুন reference।

৩. পুরোনো value-এর উপর ভিত্তি করে update

Word counter — classic example:

use std::collections::HashMap;

let text = "hello world wonderful world";

let mut map = HashMap::new();

for word in text.split_whitespace() {
    let count = map.entry(word).or_insert(0);
    *count += 1;
}

println!("{map:?}"); // {"world": 2, "hello": 1, "wonderful": 1}

or_insert(0) মুতাবিক value-র &mut V ফেরত পাই — *count দিয়ে dereference করে increment।

Hashing function

Default-এ HashMap SipHash ব্যবহার করে — DoS attack (hash collision deliberately তৈরি করার চেষ্টা) থেকে protect করে। সবচেয়ে fast না, কিন্তু security trade-off worth।

অন্য hasher চাইলে — BuildHasher trait implement-করা type ব্যবহার করতে হবে। crates.io-এ alternative library আছে।

এই পাঠ থেকে যা শিখলে

  • use std::collections::HashMap দরকার; HashMap::new() দিয়ে create।
  • .insert(k, v) add/overwrite; .get(&k) Option return।
  • String-এর মতো owned key/value insert করলে ownership map-এ চলে যায়।
  • .entry(k).or_insert(default) — absent-only insert + mutable reference।
  • *count += 1 pattern — counter ও update-by-old-value।
  • Default hasher SipHash, swap-able।