C#進階學習(七)常見的泛型數據結構類(2)HashSet和SortedSet

????????

目錄

using System.Collections.Generic; // 核心命名空間

一、?HashSet

核心特性

常用方法

屬性

二、SortedSet

核心特性

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?并賦值給?actualValueif (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}
}

?

屬性

屬性名類型說明示例代碼
Countint集合中元素的數量int count = hashSet.Count;
ComparerIEqualityComparer<T>用于比較元素的相等性比較器var comparer = hashSet.Comparer;

?????????這個比較器,主要是用來自定義相同規則

二、SortedSet<T>

核心特性

  • 唯一性:保證元素唯一性。

  • 有序性:元素按升序自動排列(默認使用?IComparer<T>?或元素的自然順序)。

  • 底層實現:基于紅黑樹(Red-Black Tree),一種自平衡二叉搜索樹。

  • 適用場景:需要有序唯一元素的集合、范圍查詢(如獲取某個區間內的元素)。

????????這個排序指的是怎么個排序法則呢:

SortedSet<T> 默認按元素的 自然順序(IComparable<T> 接口)排序

看都看不懂上面那句話,來我們接著往下看,對于不同的類型具有不同的排序方式:

1、整型(intlong?等)

按數值升序排列。

示例:{ 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}
}

?

屬性

屬性名類型說明示例代碼
Countint集合中元素的數量int count = sortedSet.Count;
ComparerIComparer<T>用于排序元素的比較器var comparer = sortedSet.Comparer;
MinT集合中的最小元素int min = sortedSet.Min;
MaxT集合中的最大元素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>?額外提供有序相關的功能(如?MinMaxGetViewBetween)。

根據需求選擇:

速度優先?→?HashSet<T>

順序優先?→?SortedSet<T>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78113.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78113.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78113.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SQL之DML(查詢語句:select、where)

&#x1f3af; 本文專欄&#xff1a;MySQL深入淺出 &#x1f680; 作者主頁&#xff1a;小度愛學習 select查詢語句 在開發中&#xff0c;查詢語句是使用最多&#xff0c;也是CRUD中&#xff0c;復雜度最高的sql語句。 查詢的語法結構 select *|字段1 [, 字段2 ……] from 表…

vue | 不同 vue 版本對復雜泛型的支持情況 · vue3.2 VS vue3.5

省流總結&#xff1a;defineProps 的泛型能力&#xff0c;來直接推導第三方組件的 props 類型 引入第三方庫的類型&#xff0c;并直接在 <script setup> 中作為 props 使用。這種類型一般是復雜泛型&#xff08;包含聯合類型、可選屬性、交叉類型、條件類型等&#xff0…

Unity-無限滾動列表實現Timer時間管理實現

今天我們來做一個UI里經常做的東西&#xff1a;無限滾動列表。 首先我們得寫清楚實現的基本思路&#xff1a; 所謂的無限滾動當然不是真的無限滾動&#xff0c;我們只要把離開列表的框再丟到列表的后面就行&#xff0c;核心理念和對象池是類似的。 我們來一點一點實現&#x…

Docker的基本概念和一些運用場景

Docker 是一種開源的容器化平臺&#xff0c;可以幫助開發人員更加高效地打包、發布和運行應用程序。以下是 Docker 的基本概念和優勢&#xff1a; 基本概念&#xff1a; 容器&#xff1a;Docker 使用容器來打包應用程序及其依賴項&#xff0c;容器是一個獨立且可移植的運行環境…

Unity中基于第三方插件擴展的對于文件流處理的工具腳本

在Unity的項目中對應文件處理,在很多地方用到,常見的功能,就是保存文件,加載文件,判斷文件或者文件夾是否存在,刪除文件等。 在之前已經寫過通過C#的IO實現的這些功能,可查看《Unity C# 使用IO流對文件的常用操作》,但是不能保證所有平臺都可以使用 現在基于第三方跨…

Flink介紹——實時計算核心論文之MillWheel論文詳解

引入 通過前面的文章&#xff0c;我們從S4到Storm&#xff0c;再到Storm結合Kafka成為當時的實時處理最佳實踐&#xff1a; S4論文詳解S4論文總結Storm論文詳解Storm論文總結Kafka論文詳解Kafka論文總結 然而KafkaStorm的第一代流式數據處理組合&#xff0c;還面臨的三個核心…

python異步協程async調用過程圖解

1.背景&#xff1a; 項目中有用到協程&#xff0c;但是對于協程&#xff0c;線程&#xff0c;進程的區別還不是特別了解&#xff0c;所以用圖示的方式畫了出來&#xff0c;用于理清三者的概念。 2.概念理解&#xff1a; 2.1協程&#xff0c;線程&#xff0c;進程包含關系 一…

【React】獲取元素距離頁面頂部的距離

文章目錄 代碼實現 代碼實現 import { useEffect, useRef, useState } from react;const DynamicPositionTracker () > {const [distance, setDistance] useState(0);const divRef useRef(null);useEffect(() > {const targetDiv divRef.current;if (!targetDiv) re…

26.OpenCV形態學操作

OpenCV形態學操作 形態學操作&#xff08;Morphological Operations&#xff09;源自二值圖像處理&#xff0c;主要用于分析和處理圖像中的結構元素&#xff0c;對圖像進行去噪、提取邊緣、分割等預處理步驟。OpenCV庫中提供了豐富的形態學函數&#xff0c;常見的包括&#xf…

邏輯回歸:損失和正則化技術的深入研究

邏輯回歸&#xff1a;損失和正則化技術的深入研究 引言 邏輯回歸是一種廣泛應用于分類問題的統計模型&#xff0c;尤其在機器學習領域中占據著重要的地位。盡管其名稱中包含"回歸"&#xff0c;但邏輯回歸本質上是一種分類算法。它的核心思想是在線性回歸的基礎上添…

大模型面經 | 介紹一下CLIP和BLIP

大家好,我是皮先生!! 今天給大家分享一些關于大模型面試常見的面試題,希望對大家的面試有所幫助。 往期回顧: 大模型面經 | 春招、秋招算法面試常考八股文附答案(RAG專題一) 大模型面經 | 春招、秋招算法面試常考八股文附答案(RAG專題二) 大模型面經 | 春招、秋招算法…

【MCP】第二篇:IDE革命——用MCP構建下一代智能工具鏈

【MCP】第二篇&#xff1a;IDE革命——用MCP構建下一代智能工具鏈 一、引言二、IDE集成MCP2.1 VSCode2.1.1 安裝VSCode2.1.2 安裝Cline2.1.3 配置Cline2.1.4 環境準備2.1.5 安裝MCP服務器2.1.5.1 自動安裝2.1.5.2 手動安裝 2.2 Trae CN2.2.1 安裝Trae CN2.2.2 Cline使用2.2.3 內…

【新能源科學與技術】MATALB/Simulink小白教程(一)實驗文檔【新能源電力轉換與控制仿真】

DP讀書&#xff1a;新能源科學與工程——專業課「新能源發電系統」 2025a 版本 MATLAB下面進入正題 仿真一&#xff1a;Buck 電路一、仿真目的二、仿真內容&#xff08;一&#xff09;Buck電路基本構成及工作原理&#xff08;二&#xff09;Buck電路仿真模型及元件連接&#xf…

BootStrap:首頁排版(其一)

今天我要介紹的是在BootStrap中有關于首頁排版的內容知識點&#xff0c;即&#xff08;模態框&#xff0c;選項卡&#xff09;。 模態框&#xff1a; 模態框經過了優化&#xff0c;更加靈活&#xff0c;以彈出對話框的形式出現&#xff0c;具有最小和最實用的功能集。 在運行…

Spring Data

目錄 一、Spring Data 簡介與生態概覽 什么是 Spring Data&#xff1f; Spring Data 與 Spring Data JPA 的關系 Spring Data 家族&#xff1a;JPA、MongoDB、Redis、Elasticsearch、JDBC、R2DBC…… 與 MyBatis 的本質差異&#xff08;ORM vs SQL 顯式控制&#xff09; 二…

建筑末端配電回路用電安全解決方案

一、電氣火災的嚴峻現狀 根據國家應急管理部消防救援局的數據&#xff0c;電氣火災長期占據各類火災原因之首&#xff0c;2021年占比高達50.4%。其中&#xff0c;末端配電回路因保護不足、監測手段落后&#xff0c;成為火災高發隱患點。私拉電線、線路老化、接觸不良、過載等問…

華為開發崗暑期實習筆試(2025年4月16日)

刷題小記&#xff1a; 第一題懷疑測試樣例不完整&#xff0c;貪心法不應該能夠解決該題。第二題使用0-1BFS解決單源最短路徑的問題&#xff0c;往往搭配雙端隊列實現。第三題是運用動態規劃解決最大不重疊子區間個數的問題&#xff0c;難點在于滿足3重判斷規則&#xff0c;所需…

Rust: 從內存地址信息看內存布局

內存布局其實有幾個&#xff1a;address&#xff08;地址&#xff09;、size&#xff08;大小&#xff09;、alignment&#xff08;對齊位數&#xff0c;2 的自然數次冪&#xff0c;2&#xff0c;4&#xff0c;8…&#xff09;。 今天主要從address來看內存的布局。 說明&…

每日一題算法——兩個數組的交集

兩個數組的交集 力扣題目鏈接 我的解法&#xff1a;利用數組下標。 缺點&#xff1a;當取值范圍很大時&#xff0c;浪費空間。 class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {int count1[1001]{0…

c++ 互斥鎖

為練習c 線程同步&#xff0c;做了LeeCode 1114題. 按序打印&#xff1a; 給你一個類&#xff1a; public class Foo {public void first() { print("first"); }public void second() { print("second"); }public void third() { print("third"…