HashSet<T> là tập hợp (set) không thứ tự, không cho phép phần tử trùng lặp, tối ưu cho tra cứu, thêm, xóa O(1) trung bình. Nằm trong namespace System.Collections.Generic.
Đặc điểm chính
- Không giữ thứ tự thêm vào.
- Không cho phép phần tử trùng (dựa trên
GetHashCode()vàEquals()). - Hiệu năng cao:
Add,Remove,Contains~ O(1). - Hỗ trợ phép toán tập hợp: Union, Intersect, Except, SymmetricExcept, IsSubsetOf, IsSupersetOf...
Ví dụ: Loại bỏ trùng lặp từ mảng
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
string[] arr1 = { "bus", "truck", "bus", "car", "truck" };
Console.WriteLine("Gốc: " + string.Join(", ", arr1));
// Tạo HashSet từ mảng - tự động loại trùng
var hashSet = new HashSet<string>(arr1);
// Chuyển lại mảng (thứ tự không đảm bảo)
string[] arr2 = hashSet.ToArray();
Console.WriteLine("Sau HashSet: " + string.Join(", ", arr2));
// Hoặc dùng LINQ Distinct() (giữ thứ tự xuất hiện đầu tiên)
string[] distinct = arr1.Distinct().ToArray();
Console.WriteLine("LINQ Distinct: " + string.Join(", ", distinct));
}
}
Kết quả
Gốc: bus, truck, bus, car, truck Sau HashSet: bus, truck, car (thứ tự có thể khác) LINQ Distinct: bus, truck, car
Các phép toán tập hợp hữu ích
var setA = new HashSet<int> { 1, 2, 3, 4 };
var setB = new HashSet<int> { 3, 4, 5, 6 };
setA.UnionWith(setB); // {1,2,3,4,5,6} - Hợp
setA.IntersectWith(setB); // {3,4} - Giao
setA.ExceptWith(setB); // {1,2} - Hiệu (A - B)
setA.SymmetricExceptWith(setB); // {1,2,5,6} - Hiệu đối xứng
So sánh HashSet vs List vs Dictionary
| Thao tác | List<T> | Dictionary<TKey,TValue> | HashSet<T> |
|---|---|---|---|
| Contains | O(n) | O(1) | O(1) |
| Add | O(1)* | O(1) | O(1) |
| Remove | O(n) | O(1) | O(1) |
| Cho phép trùng | Có | Key không trùng | Không |
| Giữ thứ tự | Có | Không (từ .NET 6 có OrderedDictionary) | Không |
Mẹo: Dùng HashSet khi cần kiểm tra sự tồn tại nhanh, loại trùng, hoặc phép toán tập hợp. Dùng List khi cần thứ tự, truy cập bằng index. Dùng Dictionary khi cần ánh xạ Key → Value.