????????
目錄
using System.Collections.Generic; // 核心命名空間
核心特性
常用方法
屬性
核心特性
1、整型(int、long?等)
2、字符串型(string)?
3、字符型(char)
4、自定義對象
常用方法
屬性
三、?HashSet ?和?SortedSet ?方法對比表
共有方法
獨有方法
四、HashSet中的自定義相等方法與SortedSet中的自定義排序方式的示例?
4-1HashSet示例,不區分大小寫:
4-2SortedSet自定義比較器(按字符串長度排序和倒序排數字)
五、總結
???????
?????????注意本文提到的數據結構需在比較新的.NET框架上使用,不然會出錯?
必須引用的命名空間:
using System.Collections.Generic; // 核心命名空間
一、?HashSet<T>
核心特性
唯一性:保證集合中元素的唯一性(通過?
GetHashCode
?和?Equals
?判斷重復)。無序性:元素的存儲和遍歷順序與插入順序無關,也不保證任何特定順序。
底層實現:基于哈希表(Hash Table),使用桶(Buckets)和鏈表/開放尋址解決哈希沖突。
適用場景:快速判斷元素是否存在、去重、集合運算(并集、交集、差集)。
創造方式:
// 默認構造函數
var hashSet1 = new HashSet<int>();// 從集合初始化
var hashSet2 = new HashSet<int>(new[] { 1, 2, 3 });// 指定自定義相等比較器
var hashSet3 = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
?
常用方法
方法名 | 參數 | 返回值/行為 | 示例代碼 |
---|---|---|---|
Add(T item) | 要添加的元素 | 返回?bool (是否添加成功) | hashSet.Add(5); |
Remove(T item) | 要刪除的元素 | 返回?bool (是否刪除成功) | hashSet.Remove(2); |
Contains(T item) | 要檢查的元素 | 返回?bool (是否包含元素) | if (hashSet.Contains(3)) { ... } |
Clear() | 無 | 清空所有元素 | hashSet.Clear(); |
UnionWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為與另一個集合的并集 | hashSet.UnionWith(otherSet); |
IntersectWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為與另一個集合的交集 | hashSet.IntersectWith(otherSet); |
ExceptWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為當前集合減去另一個集合(差集) | hashSet.ExceptWith(otherSet); |
SymmetricExceptWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為僅包含存在于當前集合或另一集合但不同時存在的元素(對稱差集) | hashSet.SymmetricExceptWith(otherSet); |
IsSubsetOf(IEnumerable<T>) | 另一個集合 | 返回?bool (當前集合是否是另一個集合的子集) | bool isSubset = hashSet.IsSubsetOf(otherSet); |
IsSupersetOf(IEnumerable<T>) | 另一個集合 | 返回?bool (當前集合是否是另一個集合的超集) | bool isSuperset = hashSet.IsSupersetOf(otherSet); |
Overlaps(IEnumerable<T>) | 另一個集合 | 返回?bool (當前集合與另一個集合是否有交集) | bool overlaps = hashSet.Overlaps(otherSet); |
SetEquals(IEnumerable<T>) | 另一個集合 | 返回?bool (當前集合是否與另一個集合元素完全相同) | bool equals = hashSet.SetEquals(otherSet); |
CopyTo(T[] array) | 目標數組 | 將集合元素復制到數組中 | int[] arr = new int[10]; hashSet.CopyTo(arr); |
TryGetValue(T equalValue, out T actualValue) | 查找的值?equalValue | 如果找到相等元素,返回?true ?并賦值給?actualValue | if (hashSet.TryGetValue(5, out int val)) { ... } |
主要使用演示:
using System;
using System.Collections.Generic;public class HashSetExample
{public static void Main(){// 初始化 HashSetConsole.WriteLine("---------------------------------1、初始化--------------------------------------------");var hashSet = new HashSet<int> { 1, 2, 3 };Console.WriteLine("初始集合: " + string.Join(", ", hashSet)); // 輸出: 1, 2, 3Console.WriteLine("---------------------------------2、增加元素--------------------------------------------");// 添加元素bool added = hashSet.Add(4);Console.WriteLine($"添加 4 成功?{added}"); // trueadded = hashSet.Add(2);Console.WriteLine($"重復添加 2 成功?{added}"); // falseConsole.WriteLine("---------------------------------3、查找元素--------------------------------------------");// 檢查元素存在性Console.WriteLine("是否包含 3?" + hashSet.Contains(3)); // trueConsole.WriteLine("---------------------------------4、刪除元素--------------------------------------------");// 刪除元素bool removed = hashSet.Remove(2);Console.WriteLine($"刪除 2 成功?{removed}"); // trueConsole.WriteLine("---------------------------------5、集合運算--------------------------------------------");// 集合運算var otherSet = new HashSet<int> { 3, 4, 5 };// 并集(合并兩個集合的元素)hashSet.UnionWith(otherSet);Console.WriteLine("并集后: " + string.Join(", ", hashSet)); // 1, 3, 4, 5// 交集(保留共同元素)hashSet.IntersectWith(new[] { 3, 4 });Console.WriteLine("交集后: " + string.Join(", ", hashSet)); // 3, 4// 差集(移除當前集合中與另一集合重復的元素)hashSet.ExceptWith(new[] { 3 });Console.WriteLine("差集后: " + string.Join(", ", hashSet)); // 4// 對稱差集(僅保留不重復的元素)hashSet.SymmetricExceptWith(new[] { 4, 5, 6 });Console.WriteLine("對稱差集后: " + string.Join(", ", hashSet)); // 5, 6Console.WriteLine("---------------------------------6、獲取存在的元素使用--------------------------------------------");// TryGetValue(查找元素)if (hashSet.TryGetValue(5, out int value)){Console.WriteLine($"找到元素: {value}"); // 5}Console.WriteLine("---------------------------------7、清空元素--------------------------------------------");// 清空集合hashSet.Clear();Console.WriteLine("清空后元素數量: " + hashSet.Count); // 0}
}
?
屬性
屬性名 | 類型 | 說明 | 示例代碼 |
---|---|---|---|
Count | int | 集合中元素的數量 | int count = hashSet.Count; |
Comparer | IEqualityComparer<T> | 用于比較元素的相等性比較器 | var comparer = hashSet.Comparer; |
?????????這個比較器,主要是用來自定義相同規則
二、SortedSet<T>
核心特性
唯一性:保證元素唯一性。
有序性:元素按升序自動排列(默認使用?
IComparer<T>
?或元素的自然順序)。底層實現:基于紅黑樹(Red-Black Tree),一種自平衡二叉搜索樹。
適用場景:需要有序唯一元素的集合、范圍查詢(如獲取某個區間內的元素)。
????????這個排序指的是怎么個排序法則呢:
SortedSet<T> 默認按元素的 自然順序(IComparable<T> 接口)排序
看都看不懂上面那句話,來我們接著往下看,對于不同的類型具有不同的排序方式:
1、整型(int
、long
?等)
按數值升序排列。
示例:
{ 5, 3, 9 }
?→ 排序后為?{ 3, 5, 9 }
。
2、字符串型(string
)?
按字典序(區分大小寫)排序。
示例:
{ "Banana", "apple", "Cherry" }
?→ 排序后為?{ "Banana", "Cherry", "apple" }
(ASCII 值:B=66
,?C=67
,?a=97
)。
3、字符型(char
)
按 Unicode 碼點升序排序。
示例:
{ 'C', 'a', '1' }
?→ 排序后為?{ '1' (U+0031), 'C' (U+0043), 'a' (U+0061) }
。
4、自定義對象
????????若未實現?IComparable<T>
,需通過構造函數指定?IComparer<T>
,否則會拋出異常。
初始化方式:
// 默認構造函數(按自然順序排序)
var sortedSet1 = new SortedSet<int>();// 從集合初始化
var sortedSet2 = new SortedSet<int>(new[] { 3, 1, 2 });// 指定自定義比較器
var sortedSet3 = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
?
常用方法
方法名 | 參數 | 返回值/行為 | 示例代碼 |
---|---|---|---|
Add(T item) | 要添加的元素 | 返回?bool (是否添加成功) | sortedSet.Add(5); |
Remove(T item) | 要刪除的元素 | 返回?bool (是否刪除成功) | sortedSet.Remove(2); |
Contains(T item) | 要檢查的元素 | 返回?bool (是否包含元素) | if (sortedSet.Contains(3)) { ... } |
Clear() | 無 | 清空所有元素 | sortedSet.Clear(); |
UnionWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為與另一個集合的并集 | sortedSet.UnionWith(otherSet); |
IntersectWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為與另一個集合的交集 | sortedSet.IntersectWith(otherSet); |
ExceptWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為當前集合減去另一個集合(差集) | sortedSet.ExceptWith(otherSet); |
SymmetricExceptWith(IEnumerable<T>) | 另一個集合 | 將當前集合修改為僅包含存在于當前集合或另一集合但不同時存在的元素(對稱差集) | sortedSet.SymmetricExceptWith(otherSet); |
GetViewBetween(T lower, T upper) | 下限?lower ?和上限?upper | 返回一個子集視圖,包含介于?lower ?和?upper ?之間的元素 | var subset = sortedSet.GetViewBetween(2, 5); |
CopyTo(T[] array) | 目標數組 | 將集合元素復制到數組中 | int[] arr = new int[10]; sortedSet.CopyTo(arr); |
Reverse() | 無 | 返回一個按降序排列的?IEnumerable<T> | foreach (var item in sortedSet.Reverse()) { ... } |
使用演示:
using System;
using System.Collections.Generic;public class SortedSetExample
{public static void Main(){Console.WriteLine("---------------------------------1、初始化--------------------------------------------");// 初始化 SortedSet(默認升序)var sortedSet = new SortedSet<int> { 5, 2, 8, 1 };Console.WriteLine("初始集合: " + string.Join(", ", sortedSet)); // 1, 2, 5, 8Console.WriteLine("---------------------------------2、添加元素--------------------------------------------");// 添加元素bool added = sortedSet.Add(3);Console.WriteLine($"添加 3 成功?{added}"); // trueadded = sortedSet.Add(2);Console.WriteLine($"重復添加 2 成功?{added}"); // falseConsole.WriteLine("---------------------------------3、查詢是否存在某個元素--------------------------------------------");// 檢查元素存在性Console.WriteLine("是否包含 5?" + sortedSet.Contains(5)); // trueConsole.WriteLine("---------------------------------4、刪除某一個元素--------------------------------------------");// 刪除元素bool removed = sortedSet.Remove(8);Console.WriteLine($"刪除 8 成功?{removed}"); // trueConsole.WriteLine("---------------------------------5、集合運算--------------------------------------------");// 集合運算var otherSet = new SortedSet<int> { 3, 4, 5 };// 并集sortedSet.UnionWith(otherSet);Console.WriteLine("并集后: " + string.Join(", ", sortedSet)); // 1, 2, 3, 4, 5// 交集sortedSet.IntersectWith(new[] { 2, 3, 4 });Console.WriteLine("交集后: " + string.Join(", ", sortedSet)); // 2, 3, 4// 范圍查詢(獲取介于 3 和 5 之間的元素視圖)var subset = sortedSet.GetViewBetween(3, 5);Console.WriteLine("范圍查詢結果: " + string.Join(", ", subset)); // 3, 4Console.WriteLine("---------------------------------5、最大值最小值--------------------------------------------");// 直接獲取最小值和最大值Console.WriteLine($"最小值: {sortedSet.Min}, 最大值: {sortedSet.Max}"); // 2, 4// 逆序遍歷(降序)Console.Write("逆序遍歷: ");foreach (var num in sortedSet.Reverse()){Console.Write(num + " "); // 4, 3, 2}Console.WriteLine();// 清空集合sortedSet.Clear();Console.WriteLine("清空后元素數量: " + sortedSet.Count); // 0}
}
?
屬性
屬性名 | 類型 | 說明 | 示例代碼 |
---|---|---|---|
Count | int | 集合中元素的數量 | int count = sortedSet.Count; |
Comparer | IComparer<T> | 用于排序元素的比較器 | var comparer = sortedSet.Comparer; |
Min | T | 集合中的最小元素 | int min = sortedSet.Min; |
Max | T | 集合中的最大元素 | int max = sortedSet.Max; |
?
三、?HashSet<T>
?和?SortedSet<T>
?方法對比表
共有方法
方法名 | HashSet<T> ?支持 | SortedSet<T> ?支持 | 說明 |
---|---|---|---|
Add(T) | ?? | ?? | 添加元素 |
Remove(T) | ?? | ?? | 刪除元素 |
Contains(T) | ?? | ?? | 檢查元素是否存在 |
Clear() | ?? | ?? | 清空集合 |
UnionWith(IEnumerable<T>) | ?? | ?? | 并集操作 |
IntersectWith(IEnumerable<T>) | ?? | ?? | 交集操作 |
ExceptWith(IEnumerable<T>) | ?? | ?? | 差集操作 |
SymmetricExceptWith(IEnumerable<T>) | ?? | ?? | 對稱差集操作 |
CopyTo(T[]) | ?? | ?? | 復制到數組 |
獨有方法
方法名 | HashSet<T> ?特有 | SortedSet<T> ?特有 | 說明 |
---|---|---|---|
TryGetValue(T, out T) | ?? | ? | 查找并返回元素(哈希表特性) |
GetViewBetween(T, T) | ? | ?? | 獲取子集視圖(有序特性) |
Reverse() | ? | ?? | 返回降序迭代器(有序特性) |
Min ?/?Max | ? | ?? | 直接獲取最小/最大值(有序特性) |
四、HashSet中的自定義相等方法與SortedSet中的自定義排序方式的示例?
4-1HashSet示例,不區分大小寫:
第一步,實現一個IEqualityComparer接口
//比較接口
public class InsensitiveComparer : IEqualityComparer<string>
{//判斷兩個字符串是否相等 不判斷類型public bool Equals(string? x, string? y){//使用系統給我們實現好的 直接忽略大小寫return string.Equals(x,y,StringComparison.OrdinalIgnoreCase);}//生成字符串的哈希碼(不區分大小寫)public int GetHashCode([DisallowNull] string obj){//將字符串統一轉為大寫后生成哈希碼return obj.ToUpper().GetHashCode();}
}
第二步,在初始化集合時new 一個接口,這里是里氏替換原則哦
HashSet<string> haseSetString = new HashSet<string>(new InsensitiveComparer())
{"Apple","apple","Banana"
};
Console.WriteLine(haseSetString.Count);
Console.WriteLine(haseSetString.Contains("APPLE"));
?
4-2SortedSet自定義比較器(按字符串長度排序和倒序排數字)
第一步、實現IComparer接口:
public class StringLengthComparer : IComparer<string>
{public int Compare(string? x, string? y){// 按長度升序,若長度相同則按字典序int lengthCompare = x.Length.CompareTo(y.Length);return lengthCompare != 0 ? lengthCompare : string.Compare(x, y, StringComparison.Ordinal);}
}public class ReverseIntComparer : IComparer<int>
{public int Compare(int x, int y){// 默認升序是 x.CompareTo(y),降序則反轉//y 比較與 x//誰小 誰放前return y.CompareTo(x);}
}
第二步、初始化時new 一個接口對象
//1.自定義字符串長度使用
var sortedSetString = new SortedSet<string>(new StringLengthComparer())
{"Banana", "Apple", "Cherry", "Kiwi"
};
Console.WriteLine("按長度排序:");
foreach (var item in sortedSet)
{Console.WriteLine(item); // 輸出順序:Kiwi → Apple → Banana → Cherry
}//2.倒序排數字
// 使用自定義比較器初始化 SortedSet
var sortedSetInt = new SortedSet<int>(new ReverseIntComparer())
{5, 3, 9, 1
};Console.WriteLine("降序排序:");
foreach (var num in sortedSetInt)
{Console.Write(num + " "); // 輸出:9 5 3 1
}
#endregion
五、總結
HashSet<T>
?的核心是快速查找和集合運算,適用于無序唯一集合。
SortedSet<T>
?的核心是維護有序性和范圍查詢,適用于需要排序的場景。兩者共享大部分集合操作方法,但?
SortedSet<T>
?額外提供有序相關的功能(如?Min
、Max
、GetViewBetween
)。
根據需求選擇:
速度優先?→?
HashSet<T>
順序優先?→?
SortedSet<T>