HashSet
Рассмотрим HashSet как HashMap в
котором мы заботимся только о ключах (в действительности,
HashSet<T> - это просто адаптер к
HashMap<T, ()>).
"Какой в этом смысл?", - спросите вы. - "Я бы мог просто хранить
ключи в Vec."
Уникальная особенность HashSet в том, что он
гарантирует, что в нём не содержится повторяющихся элементом.
Это условие выполняет любой набор (set). HashSet -
всего лишь одна реализация (смотрите также:
BTreeSet).
Если вы вставите значение, которое уже содержится в
HashSet, (например, новое значение равно
существующему значению и они оба имеют одинаковый хэш), то
новое значение заменит старое.
Это хорошо подходит для случаев, когда вы не хотите иметь в коллекции больше одного "чего-либо" или когда вам необходимо знать имеете ли вы что-либо.
Но наборы могут делать гораздо более.
Наборы имеют 4 основные операции (все вызовы вернут итератор):
-
union: получить все уникальные элементы из обоих наборов. -
difference: получить все элементы, представленные в первом наборе, но отсутствующие во втором. -
intersection: получить только те элементы, которые присутствуют в обоих наборах. -
symmetric_difference: получить элементы содержащиеся либо только в первом наборе, либо только во втором, но не в обоих (xor).
Попробуем эти методы в следующем примере:
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), "Значение 4 уже есть в наборе B!"); // ИСПРАВЬТЕ ^ Закомментируйте эту строку b.insert(5); // Если элементы коллекции реализуют `Debug`, // то и сама коллекция реализует `Debug`. // Обычно, элементы выводятся в формате `[elem1, elem2, ...]` println!("A: {:?}", a); println!("B: {:?}", b); // Выведет [1, 2, 3, 4, 5] в произвольном порядке println!("Union: {:?}", a.union(&b).collect::<Vec<&i32>>()); // Выведет только [1] println!("Difference: {:?}", a.difference(&b).collect::<Vec<&i32>>()); // Выведет [2, 3, 4] в произвольном порядке. println!("Intersection: {:?}", a.intersection(&b).collect::<Vec<&i32>>()); // Выведет [1, 5] println!("Symmetric Difference: {:?}", a.symmetric_difference(&b).collect::<Vec<&i32>>()); }
(Пример адаптирован из документации)