HashSet<T> is Rust's implementation of a hash set - a collection of unique values with O(1) average-time complexity for insertions, lookups, and removals. Unlike Vec, a HashSet automatically ensures that no duplicate values exist, making it perfect for deduplication and membership testing.
The HashSet type is found in std::collections and requires that elements implement both Hash and Eq traits. Most primitive types and many standard library types already implement these traits, so you can use them directly.
Beyond basic operations like insert() and contains(), HashSet provides powerful set-theoretic operations: union() (elements in either set), intersection() (elements in both sets), difference() (elements in one set but not the other), and symmetric_difference() (elements in exactly one set).
use std::collections::HashSet;
let mut set: HashSet<i32> = HashSet::new();
set.insert(1);
set.insert(2);
set.insert(2); // Duplicate, won't be added
assert_eq!(set.len(), 2);
assert!(set.contains(&1));
// Creating from an iterator
let set: HashSet<_> = vec![1, 2, 3, 2, 1]
.into_iter()
.collect();
assert_eq!(set.len(), 3); // Only unique valuesImplement the following functions for working with HashSet:
unique_elements(items: &[i32]) -> HashSet<i32>
count_unique(items: &[i32]) -> usize
find_common(set1: &HashSet<i32>, set2: &HashSet<i32>) -> HashSet<i32> - Return elements that appear in both sets (intersection)
find_all(set1: &HashSet<i32>, set2: &HashSet<i32>) -> HashSet<i32> - Return elements that appear in either set (union)
find_difference(set1: &HashSet<i32>, set2: &HashSet<i32>) -> HashSet<i32> - Return elements in set1 that are not in set2 (difference)
find_symmetric_difference(set1: &HashSet<i32>, set2: &HashSet<i32>) -> HashSet<i32> - Return elements that are in exactly one of the sets (symmetric difference)
is_subset(potential_subset: &HashSet<i32>, potential_superset: &HashSet<i32>) -> bool
potential_subset are
contained in potential_supersetuse std::collections::HashSet;
// unique_elements
let items = vec![1, 2, 3, 2, 1, 4, 3];
let unique = unique_elements(&items);
assert!(unique.contains(&1));
assert!(unique.contains(&4));
assert_eq!(unique.len(), 4);
// count_unique
assert_eq!(count_unique(&[1, 2, 2, 3, 3, 3]), 3);
// find_common (intersection)
let set1: HashSet<i32> = [1, 2, 3].into_iter().collect();
let set2: HashSet<i32> = [2, 3, 4].into_iter().collect();
let common = find_common(&set1, &set2);
assert_eq!(
common,
[2, 3].into_iter().collect()
);
// find_all (union)
let all = find_all(&set1, &set2);
assert_eq!(
all,
[1, 2, 3, 4].into_iter().collect()
);
// find_difference
// In set1 but not set2
let diff = find_difference(&set1, &set2);
assert_eq!(
diff,
[1].into_iter().collect()
);
// find_symmetric_difference
// In exactly one set
let sym_diff = find_symmetric_difference(&set1, &set2);
assert_eq!(
sym_diff,
[1, 4].into_iter().collect()
);
// is_subset
let small: HashSet<i32> = [2, 3]
.into_iter()
.collect();
let large: HashSet<i32> = [1, 2, 3, 4]
.into_iter()
.collect();
assert!(is_subset(&small, &large));
assert!(!is_subset(&large, &small));unique_elements, you can iterate over the slice and collect into a HashSet, or use .iter().cloned().collect()count_unique, you can create a set and return its lengthfind_common, use the .intersection() method, which returns an iteratorfind_all, use the .union() methodfind_difference, use the .difference() methodfind_symmetric_difference, use the .symmetric_difference() methodis_subset, use the .is_subset() method