HashSet 是一個高效能的集合類型,和 List 除了速度以外的差別在於 HashSet 不予許重複,且沒有順序。HashSet 使用 Hash 來存取元素,使用他的主要因素就是因為速度非常快,檢索的時間複雜度為 O(1)。如果需要速度快但是需要記錄順序的可以改為使用 SortedSet ,檢索的時間複雜度為 O(Log N),但是一樣也不會儲存重複的資料。
HashSet, SortedSet, List 三者的速度比較如下:
可以發現平時最常使用的 List 在大量存取下顯得有點吃力,反倒是 HashSet, SortedSet 非常快速。
只是 HashSet 和 SortedSet 與 List 相比還多了 Overlaps, IsSubsetOf, IsProperSubsetOf 等數學集合運算方法可以使用。
參考資料:
Microsoft.Learn - HashSet<T> Class
Microsoft.Learn - SortedSet<T> Class
速度比較
這裡做一個不嚴謹的測試,將 50 萬筆資料插入,再逐一檢查是否包含此資料,測試方式如下:
HashSet<int> hashSet = new HashSet<int>();
for (int i = 1; i <= 500000; i++)
{
hashSet.Add(i);
}
// 計時
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
// 搜尋
for (int i = 1; i <= 500000; i++)
{
var contains = hashSet.Contains(i);
}
stopwatch.Stop();
Console.WriteLine($"HashSet: {stopwatch.ElapsedMilliseconds} ms");
HashSet, SortedSet, List 三者的速度比較如下:
// HashSet: 3 ms
// SortedSet: 46 ms
// List: 27089 ms
可以發現平時最常使用的 List 在大量存取下顯得有點吃力,反倒是 HashSet, SortedSet 非常快速。
基礎操作
HashSet 和 SortedSet 都有實作 ISet 介面,所以基礎操作都差不多:
HashSet<int> hashSet = new HashSet<int> ();
hashSet.Add(1);
hashSet.Add(1);
hashSet.Add(2);
Console.WriteLine(hashSet.Count); // 2
var contains = hashSet.Contains(1);
Console.WriteLine(contains); // true
hashSet.Remove(1);
Console.WriteLine(hashSet.Count); // 1
foreach (var i in hashSet)
{
Console.WriteLine(i);
}
只是 HashSet 和 SortedSet 與 List 相比還多了 Overlaps, IsSubsetOf, IsProperSubsetOf 等數學集合運算方法可以使用。
參考資料:
Microsoft.Learn - HashSet<T> Class
Microsoft.Learn - SortedSet<T> Class
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com