HashSet
Розглядайте HashSet як HashMap, де ми просто дбаємо про ключі (
HashSet<T> фактично є лише обгорткою навколо HashMap<T, ()>).
“Який у цьому сенс?” — запитуєте ви. “Я міг би просто зберігати ключі у Vec.”
Унікальна властивість HashSet полягає в тому, що
йому гарантовано не мати дубльованих елементів.
Саме це й є контракт, який виконує будь-яка колекція множин.
HashSet — лише одна з реалізацій. (див. також: BTreeSet)
Якщо ви вставляєте значення, яке вже присутнє в HashSet,
(тобто нове значення дорівнює наявному і вони обидва мають однаковий хеш),
тоді нове значення замінить старе.
Це чудово підходить для випадків, коли ви ніколи не хочете більше ніж одного чогось, або коли ви хочете знати, чи вже маєте щось.
Але множини можуть робити більше, ніж це.
Множини мають 4 основні операції (усі такі виклики повертають ітератор):
-
union: отримати всі унікальні елементи в обох множинах. -
difference: отримати всі елементи, які є в першій множині, але не в другій. -
intersection: отримати всі елементи, які є тільки в обох множинах. -
symmetric_difference: отримати всі елементи, які є в одній множині або в іншій, але не в обох.
Спробуйте всі ці варіанти в наведеному нижче прикладі:
use std::collections::HashSet;
fn main() {
let mut a: HashSet<i32> = vec![1i32, 2, 3].into_iter().collect();
let mut b: HashSet<i32> = vec![2i32, 3, 4].into_iter().collect();
assert!(a.insert(4));
assert!(a.contains(&4));
// `HashSet::insert()` повертає false, якщо
// значення вже було присутнє.
assert!(b.insert(4), "Value 4 is already in set B!");
// FIXME ^ Comment out this line
b.insert(5);
// If a collection's element type implements `Debug`,
// then the collection implements `Debug`.
// It usually prints its elements in the format `[elem1, elem2, ...]`
println!("A: {:?}", a);
println!("B: {:?}", b);
// Print [1, 2, 3, 4, 5] in arbitrary order
println!("Union: {:?}", a.union(&b).collect::<Vec<&i32>>());
// This should print [1]
println!("Difference: {:?}", a.difference(&b).collect::<Vec<&i32>>());
// Print [2, 3, 4] in arbitrary order.
println!("Intersection: {:?}", a.intersection(&b).collect::<Vec<&i32>>());
// Print [1, 5]
println!("Symmetric Difference: {:?}",
a.symmetric_difference(&b).collect::<Vec<&i32>>());
}
(Приклади адаптовано з документації.)