<h2>HashMap: Armazenamento Eficiente com Chaves</h2>
<p>HashMap é uma estrutura de dados que associa chaves a valores, permitindo busca, inserção e remoção em tempo O(1) médio. Em Rust, <code>HashMap</code> é implementado através de tabela hash com tratamento de colisões. Diferentemente de arrays, você não precisa de índices sequenciais — qualquer tipo que implemente <code>Hash</code> e <code>Eq</code> pode ser chave.</p>
<pre><code class="language-rust">use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
// Inserção
scores.insert("Alice", 95);
scores.insert("Bob", 87);
scores.insert("Charlie", 92);
// Acesso
match scores.get("Alice") {
Some(score) => println!("Alice: {}", score),
None => println!("Não encontrado"),
}
// Iteração
for (name, score) in &scores {
println!("{}: {}", name, score);
}
// Atualização
scores.insert("Alice", 98);
// Remoção
scores.remove("Bob");
println!("Total de alunos: {}", scores.len());
}</code></pre>
<h3>Operações Essenciais</h3>
<p>O método <code>entry()</code> é crucial para operações complexas. Ele oferece acesso otimizado quando você precisa verificar e modificar em uma única operação, evitando buscas redundantes. Use <code>or_insert()</code> para definir um valor padrão se a chave não existir.</p>
<pre><code class="language-rust">use std::collections::HashMap;
fn main() {
let mut words = HashMap::new();
// Contar frequência de palavras
let text = vec!["rust", "rust", "java", "rust", "python", "java"];
for word in text {
*words.entry(word).or_insert(0) += 1;
}
for (word, count) in words {
println!("{}: {} vezes", word, count);
}
}</code></pre>
<h2>HashSet: Conjuntos Únicos e Rápidos</h2>
<p><code>HashSet</code> é uma coleção que garante unicidade de elementos e oferece operações de conjunto eficientes. Internamente, utiliza HashMap armazenando valores como chaves com valores vazios. Use HashSet quando precisar verificar pertencimento rapidamente ou eliminar duplicatas.</p>
<pre><code class="language-rust">use std::collections::HashSet;
fn main() {
let mut tags = HashSet::new();
// Inserção (duplicatas são ignoradas)
tags.insert("rust");
tags.insert("programming");
tags.insert("rust"); // Ignorado
tags.insert("performance");
// Verificação de pertencimento
if tags.contains("rust") {
println!("Tag 'rust' existe!");
}
// Remoção
tags.remove("programming");
println!("Total de tags: {}", tags.len());
}</code></pre>
<h3>Operações de Conjunto</h3>
<p>HashSet implementa operações matemáticas de conjuntos. As operações <code>union()</code>, <code>intersection()</code> e <code>difference()</code> retornam iteradores, permitindo encadeamento eficiente. Use essas operações para resolver problemas de filtragem e análise de dados.</p>
<pre><code class="language-rust">use std::collections::HashSet;
fn main() {
let mut grupo_a: HashSet<&str> = ["alice", "bob", "charlie"].iter().cloned().collect();
let mut grupo_b: HashSet<&str> = ["bob", "charlie", "diana"].iter().cloned().collect();
// União
let union: HashSet<_> = grupo_a.union(&grupo_b).cloned().collect();
println!("União: {:?}", union);
// Interseção
let intersection: HashSet<_> = grupo_a.intersection(&grupo_b).cloned().collect();
println!("Interseção: {:?}", intersection);
// Diferença (em A mas não em B)
let difference: HashSet<_> = grupo_a.difference(&grupo_b).cloned().collect();
println!("Diferença: {:?}", difference);
}</code></pre>
<h2>Boas Práticas e Considerações de Performance</h2>
<p>A escolha entre HashMap e HashSet depende do caso de uso. Use HashMap quando precisar associar dados a chaves; use HashSet para verificação rápida de pertencimento e operações de conjunto. Ambas exigem que as chaves implementem <code>Hash</code> e <code>Eq</code>. Para tipos customizados, implemente essas traits ou use <code>#[derive(Hash, Eq, PartialEq)]</code>.</p>
<pre><code class="language-rust">use std::collections::{HashMap, HashSet};
#[derive(Hash, Eq, PartialEq, Clone, Debug)]
struct Usuario {
id: u32,
nome: String,
}
fn main() {
let mut usuarios_map: HashMap<u32, Usuario> = HashMap::new();
let mut usuarios_set: HashSet<Usuario> = HashSet::new();
let user = Usuario { id: 1, nome: "Alice".to_string() };
usuarios_map.insert(1, user.clone());
usuarios_set.insert(user);
// Evite rehashing desnecessário
let mut map_com_capacidade = HashMap::with_capacity(100);
map_com_capacidade.insert(1, "valor");
}</code></pre>
<h3>Tratamento de Colisões e Segurança</h3>
<p>Rust usa SipHash por padrão para resistir a ataques de negação de serviço baseados em colisões intencionais. Não mude o hasher sem motivo específico. Para tipos customizados, implemente a trait <code>Hash</code> corretamente: todos os campos relevantes para igualdade devem ser incluídos no hash.</p>
<h2>Conclusão</h2>
<p>HashMap e HashSet são estruturas fundamentais em Rust para operações rápidas com chaves. <strong>Primeiro</strong>: HashMap fornece associação eficiente chave-valor com O(1) médio; use <code>entry()</code> para operações complexas evitando buscas redundantes. <strong>Segundo</strong>: HashSet garante unicidade e oferece operações matemáticas poderosas como união e interseção. <strong>Terceiro</strong>: implemente corretamente <code>Hash</code> e <code>Eq</code> para tipos customizados e aproveite <code>with_capacity()</code> para otimizar alocações em casos com tamanho previsível.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://doc.rust-lang.org/book/ch08-03-hash-maps.html" target="_blank" rel="noopener noreferrer">Rust Book - Collections</a></li>
<li><a href="https://doc.rust-lang.org/std/collections/struct.HashMap.html" target="_blank" rel="noopener noreferrer">Documentação std::collections::HashMap</a></li>
<li><a href="https://doc.rust-lang.org/std/collections/struct.HashSet.html" target="_blank" rel="noopener noreferrer">Documentação std::collections::HashSet</a></li>
<li><a href="https://doc.rust-lang.org/rust-by-example/std/hash.html" target="_blank" rel="noopener noreferrer">Rust by Example - HashMap and HashSet</a></li>
<li><a href="https://doc.rust-lang.org/nightly/nomicon/hash-tables.html" target="_blank" rel="noopener noreferrer">The Rustonomicon - Hash Tables</a></li>
</ul>