use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
struct Entry<K, V> {
key: K,
value: V,
next: Option<Box<Entry<K, V>>>,
}
struct HashMap<K, V> {
buckets: Vec<Option<Box<Entry<K, V>>>>,
capacity: usize,
}
impl<K: Hash + Eq, V> HashMap<K, V> {
fn new(capacity: usize) -> Self {
let mut buckets = Vec::with_capacity(capacity);
buckets.resize_with(capacity, || None);
Self { buckets, capacity }
}
fn hash(&self, key: &K) -> usize {
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
(hasher.finish() as usize) % self.capacity
}
fn insert(&mut self, key: K, value: V) {
let index = self.hash(&key);
let mut current = &mut self.buckets[index];
while let Some(ref mut entry) = current {
if entry.key == key {
entry.value = value; // update existing key
return;
}
current = &mut entry.next;
}
let new_entry = Box::new(Entry { key, value, next: self.buckets[index].take() });
self.buckets[index] = Some(new_entry);
}
fn get(&self, key: &K) -> Option<&V> {
let index = self.hash(key);
let mut current = &self.buckets[index];
while let Some(ref entry) = current {
if &entry.key == key {
return Some(&entry.value);
}
current = &entry.next;
}
None
}
}
fn main() {
let mut map = HashMap::new(5);
map.insert("apple", 5);
map.insert("banana", 3);
map.insert("grape", 7);
println!("apple -> {:?}", map.get(&"apple"));
println!("banana -> {:?}", map.get(&"banana"));
println!("grape -> {:?}", map.get(&"grape"));
println!("orange -> {:?}", map.get(&"orange"));
}let index = self.hash(&key);
compute bucket index by hashing key
while let Some(ref mut entry) = current { if entry.key == key { entry.value = value; return; } current = &mut entry.next; }
traverse bucket linked list to update value if key exists
let new_entry = Box::new(Entry { key, value, next: self.buckets[index].take() }); self.buckets[index] = Some(new_entry);
insert new entry at head of bucket linked list to handle collisions
while let Some(ref entry) = current { if &entry.key == key { return Some(&entry.value); } current = &entry.next; }
search bucket linked list for key to get value
apple -> Some(5)
banana -> Some(3)
grape -> Some(7)
orange -> None