C# 集合

集合

  • 概述
  • 集合接口和類型
  • 列表(ArrayList, List)
  • 隊列(Queue)
  • 棧(Statck)
  • 鏈表(LinkedList)
  • 有序表(SortedList)
  • 字典
  • Lookup類
    • 其他字典類
  • HashSet(不重復項的無序列表)
  • 位數組
    • BitArray
    • BitVector32
  • 性能

概述

數組和Array類。數組的大小是固定的。如果元素個數是動態的,就應該使用集合類。
List和ArrayList是與數組相當的集合類。還有其他類型的集合:隊列、棧、鏈表和字典。
集合:

  • 集合接口和類型
  • 列表
  • 隊列
  • 鏈表
  • 有序表
  • 字典
  • Lookup
  • HashSet
  • 位數組
  • 性能

集合接口和類型

集合類可以組合為集合,存儲 Object 類型的元素和泛型集合類。在 CLR 2.0 之前,不存在泛型。現在泛型集合類通常是集合的首選類型。泛型集合類是類型安全的,如果使用值類型,是不需要裝箱操作的。如果要在集合中添加不同類型的對象,且這些對象不是相互派生的,例如在集合中添加 int和 string 對象,就只需基于對象的集合類。另一組集合類是專用于特定類型的集合,例如
StringCollection 類專用于 string 類型。

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

列表(ArrayList, List)

.NET Framework 為動態列表提供了類 ArrayList 和 List。System.Collections.Generic 命名空間中的類 List的用法非常類似于System.Collections 命名空間中的 ArrayList 類。這個類實現了 IList、ICollection 和 IEnumerable 接口。

  • 調用默認的構造函數,就可以創建列表對象。在泛型類 List中,必須在聲明中為列表的值指定類型。下面的代碼說明了如何聲明一個包含 int 的 List和一個包含 Racer 元素的列表。ArrayList是一個非泛型列表,可以將任意 Object 類型作為其元素。
  • 使用默認的構造函數創建一個空列表。元素添加到列表中后,列表的容量就會擴大為可接納 4 個元素。如果添加了第 5 個元素,列表的大小就重新設置為包含 8 個元素。如果 8 個元素還不夠,列表的大小就重新設置為 16。每次都會將列表的容量重新設置為原來的 2 倍。
ArrayList objectList = new ArrayList();
List<int> intList = new List<int>();
List<Racer> racers = new List<Racer>();

創建了一個容量為 10 個元素的集合。如果該容量不足以容納要添加的元素,就把集合的大小重新設置為 20,或 40,每次都是原來的 2 倍。

ArrayList objectList = new ArrayList(10);
List<int> intList = new List<int>(10);

使用Capacity屬性可以獲取和設置集合的容量:

objectList.Capacity = 20;
intList.Capactity = 20;

容量與集合中的個數不同。集合中元素個數可以用Count屬性讀取。當然,容量總是大于元素個數。只要不把元素添加到列表中,元素個數就是 0。

Console.WriteLine(intList.Count); // 輸出元素個數

如果已經將元素添加到列表中,且不希望添加更多的元素,就可以調用TrimExcess()方法,去除不需要的容量。但是,重新定位是需要時間的,所以如果元素個數超過了容量的 90%,TrimExcess()方法將什么也不做。

intList.TrimExcess(); // 去除不需要的容量。
ArrayList arrayList = new ArrayList();
arrayList.Add(1);
arrayList.Add(2);
arrayList.Add("Hello");
arrayList.Add(3);
arrayList.Add(4);
arrayList.Add("World");
arrayList.Add(5);// TODO:變量數組列表 
Debug.WriteLine("遍歷數組列表:"); 
foreach (var item in arrayList)
{ Debug.WriteLine(item);
}Debug.WriteLine("下標訪問數組列表:");
Debug.WriteLine(arrayList[0]);
Debug.WriteLine(arrayList[1]);
Debug.WriteLine(arrayList[2]);
Debug.WriteLine(arrayList[3]);
Debug.WriteLine(arrayList[4]);arrayList.Remove(3);    // 移除元素3            
arrayList.RemoveAt(3);  // 移除第3個元素
Debug.WriteLine("移除元素3,移除第3個元素");
foreach (var item in arrayList)
{Debug.WriteLine(item);
}arrayList.AddRange(new int[] { 10, 11, 12, 13, 14, 15 });
arrayList.RemoveRange(3, 2);int[] ints = new int[] { 34, 54, 43, 21, 66 };
arrayList.InsertRange(2, ints); // 第2個位置插入數組
foreach (var item in arrayList)
{Debug.WriteLine(item);
}//arrayList.Sort();       // 排序
//arrayList.Reverse();    // 反序foreach (var item in arrayList)
{Debug.WriteLine(item);
}//arrayList.Clear();  // 清空
//arrayList.Capacity = 10;
//Debug.WriteLine(arrayList.Count);

隊列(Queue)

隊列是其元素以先進先出(FIFO)的方式來處理的集合。先放在隊列中的元素會先讀取。隊列的例子有在機場排的隊、人力資源部中等待處理求職信的隊列、打印隊列中等待處理的打印任務、以循環方式等待 CPU 處理的線程。另外,還常常有元素根據其優先級來處理的隊列。例如,在機場的隊列中,商務艙乘客的處理要優先于經濟艙的乘客。這里可以使用多個隊列,一個隊列對應一個優先級。在機場,這是很常見的,因為商務艙乘客和經濟艙乘客有不同的登記隊列。打印隊列和線程也是這樣。可以為一組隊列建立一個數組,數組中的一項代表一個優先級。在每個數組項中,都有一個隊列,其處理按照 FIFO 的方式進行。

在這里插入圖片描述

Queue<string> queueStr = new Queue<string>();
Queue<int> queueInt = new Queue<int>(10);queueStr.Enqueue("Hi");
queueStr.Enqueue("Hello");
queueStr.Enqueue("World");
Debug.WriteLine(queueStr.Peek());
Debug.WriteLine(queueStr.Dequeue());
Debug.WriteLine(queueStr.First());
Debug.WriteLine(queueStr.Last());             
queueStr.Clear();queueInt.Enqueue(12);
queueInt.Enqueue(23);
queueInt.Enqueue(25);
queueInt.Enqueue(65);
foreach (var item in queueInt)
{Debug.WriteLine(item);
}for (int i = 0; i < queueInt.Count; i++)
{Debug.WriteLine(queueInt.Dequeue());                
}Debug.WriteLine(queueInt.Count);

棧(Statck)

棧是與隊列非常類似的另一個容器,只是要使用不同的方法訪問棧。最后添加到棧中的元素會最先讀取。棧是一個后進先出(LIFO)容器。
在這里插入圖片描述

 Stack<char> alphabet = new Stack<char>();alphabet.Push('A');alphabet.Push('B');alphabet.Push('C');            foreach (char c in alphabet){Debug.Write(c+",");}Debug.WriteLine(alphabet.Pop());foreach (char c in alphabet){Debug.Write(c + ",");}

鏈表(LinkedList)

  • LinkedList 集合類沒有非泛型集合的類似版本。LinkedList 是一個雙向鏈表,其元素指向它前面和后面的元素。
  • 鏈表的優點是,如果將元素插入列表的中間位置,使用鏈表會非常快。在插入一個元素時,只需修改上一個元素的 Next 引用和下一個元素的 Previous 引用,使它們引用所插入的元素。在 List 和ArrayList 類中,插入一個元素,需要移動該元素后面的所有元素。
  • 當然,鏈表也有缺點。鏈表的元素只能一個接一個地訪問,這需要較長的時間來查找位于鏈表中間或尾部的元素。
  • 鏈表不僅能在列表中存儲元素,還可以給每個元素存儲下一個元素和上一個元素的信息。這就是LinkedList 包含 LinkedListNode 類型的元素的原因。使用 LinkedListNode 類,可以獲得列表中的下一個元素和上一個元素。表 10-5 描述了 LinkedListNode 的屬性。
    在這里插入圖片描述
 LinkedList<string> linkedList = new LinkedList<string>();linkedList.AddLast("Apple");linkedList.AddLast("Huawei");linkedList.AddFirst("Xiaomi");linkedList.AddLast("Huawei");foreach (var item in linkedList){Debug.WriteLine(item);}var node = linkedList.Find("Apple");        // 查找元素linkedList.AddAfter(node, "Apple After");   // 在指定節點后添加元素linkedList.AddBefore(node, "Apple Before"); // 在指定節點前添加元素foreach (var item in linkedList){Debug.WriteLine(item);}Debug.WriteLine(linkedList.ElementAt(0));   // 訪問第0個元素Debug.WriteLine(linkedList.ElementAt(3));   // 訪問第3個元素

有序表(SortedList)

  • 如果需要排好序的表,可以使用 SortedList<TKey, TValue>。這個類按照鍵給元素排序。
    在這里插入圖片描述
    在這里插入圖片描述
SortedList<string, int> sortedList = new SortedList<string, int>();
sortedList.Add("one", 111);
sortedList.Add("two", 222);
sortedList.Add("three", 333);
sortedList.Add("four", 444);
sortedList.Add("five", 555);
foreach (KeyValuePair<string, int> kvp in sortedList)
{Debug.WriteLine($"key:{kvp.Key}, value:{ kvp.Value}");
}// 通過key獲取值
int value_one = sortedList["one"];// 通過索引獲取Key
int value = sortedList.Values[2];
string key_two = sortedList.Keys[2];Debug.WriteLine(value_one);
Debug.WriteLine(key_two);sortedList.Remove("one");   //  刪除鍵值對

字典

  • 字典表示一種非常復雜的數據結構,這種數據結構允許按照某個鍵來訪問元素。字典也稱為映射或散列表。字典的主要特性是能根據鍵快速查找值。也可以自由添加和刪除元素,這有點像 List,但沒有在內存中移動后續元素的性能開銷。
  • 鍵的類型:用作字典中鍵的類型必須重寫 Object 類的 GetHashCode()方法。只要字典類需要確定元素的位置,就要調用 GetHashCode()方法。GetHashCode()方法返回的 int 由字典用于計算放置元素的索引。這里不介紹這個算法。我們只需知道,它涉及到素數,所以字典的容量是一個素數。

GetHashCode()方法的實現代碼必須滿足如下要求:
● 相同的對象應總是返回相同的值。
● 不同的對象可以返回相同的值。
● 應執行得比較快,計算的開銷不大。
● 不能拋出異常。
● 應至少使用一個實例字段。
● 散列碼值應平均分布在 int 可以存儲的整個數字區域上。
● 散列碼最好在對象的生存期中不發生變化。
提示:
字典的性能取決于 GetHashCode()方法的實現代碼。

Lookup類

Dictionary<TKey, TValue>只為每個鍵支持一個值。新類 Lookup<TKey, TElement>是.NET 3.5 中新增的,它類似于 Dictionary<TKey, TValue>,但把鍵映射到一個值集上。這個類在程序集 System.Core中實現,用 System.Linq 命名空間定義。
在這里插入圖片描述

其他字典類

Dictionary<TKey, TValue>是 Framework 中的一個主要字典類,還有其他一些類,當然也有一些非泛型的字典類。
在這里插入圖片描述

HashSet(不重復項的無序列表)

.NET 3.5 在 System.Collections.Generic 命名空間中包含一個新的集合類:HashSet。這個集合類包含不重復項的無序列表。這種集合稱為"集(set)"。集是一個保留字,所以該類有另一個名稱HashSet。這個名稱很容易理解,因為這個集合基于散列值,插入元素的操作非常快,不需要像List類那樣重排集合。
在這里插入圖片描述
在這里插入圖片描述

位數組

BitArray

  • 如果需要處理許多位,就可以使用類 BitArray 和結構 BitVector32。BitArray 位于命名空間System.Collections,BitVector32 位于命名空間 System.Collections.Specialized。這兩種類型最重要的區別是,BitArray 可以重新設置大小,如果事先不知道需要的位數,就可以使用 BitArray,它可以包含非常多的位。BitVector32 是基于棧的,因此比較快。BitVector32 僅包含 32位,存儲在一個整數中。

  • 類 BitArray 是一個引用類型,包含一個 int 數組,每 32 位使用一個新整數。
    在這里插入圖片描述

BitVector32

如果事先知道需要的位數,就可以使用 BitVector32 結構替代 BitArray。BitVector32 效率較高,因為它是一個值類型,在整數棧上存儲位。一個整數可以存儲 32 位。如果需要更多的位,就可以使用多個 BitVector32 值或 BitArray。BitArray 可以根據需要增大,但 BitVector32 不能。
在這里插入圖片描述

性能

許多集合類都提供了相同的功能,例如,SortedList 與 SortedDictionary 的功能幾乎完全相同。但是,其性能常常有很大區別。一個集合使用的內存少,另一個集合的元素檢索速度快。在 MSDN 文檔中,集合的方法常常有性能提示,給出了以大 O 記號表示的操作時間:

  • O(1):表示無論集合中有多少數據項,這個操作需要的時間都不變。
  • O(n):表示對于集合中的每個元素,需要增加的時間量都是相同的。
  • O(log n):表示操作需要的時間隨集合中元素的增加而增加,但每個元素需要增加的時間不是線性的,而是呈對數曲線。

在這里插入圖片描述

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

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

相關文章

WebSocket與MQTT協議深度對比:選擇合適的通信協議

在現代互聯網應用中&#xff0c;實時通信變得愈發重要。隨著物聯網&#xff08;IoT&#xff09;和實時數據流的普及&#xff0c;選擇合適的通信協議顯得尤為關鍵。WebSocket和MQTT是當前最為流行的兩種協議&#xff0c;它們各自有不同的應用場景、優缺點以及性能特點。在這篇文…

ELK(Elasticsearch、Logstash、Kbana)安裝及Spring應用

Elasticsearch安裝及Spring應用 一、引言二、基本概念1.索引&#xff08;Index&#xff09;2.類型&#xff08;Type&#xff09;3.文檔&#xff08;Document&#xff09;4.分片&#xff08;Shard&#xff09;5.副本&#xff08;Replica&#xff09; 二、ELK搭建1.創建掛載的文件…

MacOS 15.3.1 安裝 GPG 提示Error: unknown or unsupported macOS version: :dunno

目錄 1. 問題鎖定 2. 更新 Homebrew 3. 切換到新的 Homebrew 源 4. 安裝 GPG 5. 檢查 macOS 版本兼容性 6. 使用 MacPorts 或其他包管理器 7. 創建密鑰&#xff08;生成 GPG 簽名&#xff09; 往期推薦 1. 問題鎖定 通常是因為你的 Homebrew 版本較舊&#xff0c;或者你…

C++:類和對象(從底層編譯開始)詳解[前篇]

目錄 一.inline內聯的詳細介紹 &#xff08;1&#xff09;為什么在調用內聯函數時不需要建立棧幀&#xff1a; &#xff08;2&#xff09;為什么inline聲明和定義分離到兩個文件會產生鏈接錯誤&#xff0c;鏈接是什么&#xff0c;為什么沒有函數地址&#xff1a; 二.類&…

C++中,存儲持續性、作用域和鏈接性

在C++中,存儲持續性、作用域和鏈接性是變量和函數的重要屬性,它們共同決定了變量的生命周期、可見性以及跨文件訪問能力。以下是詳細的總結: 1. 存儲持續性(Storage Duration) 存儲持續性指變量在內存中的生命周期,分為四類: 自動存儲持續性(Automatic) 局部變量(函…

四種 No-SQL

在一個常規的互聯網服務中&#xff0c;讀取與寫入的比例大約是 100:1 到 1000:1。然而&#xff0c;從硬盤讀取時&#xff0c;數據庫連接操作耗時&#xff0c;99% 的時間花費在磁盤尋址上。 為了優化讀取性能&#xff0c;非規范化的設計通過添加冗余數據或分組數據來引入。下述…

【 Manus平替開源項目】

文章目錄 Manus平替開源項目1 OpenManus1.1 簡介1.2 安裝教程1.3 運行 2 OWL2.1 簡介2.2 安裝教程2.3 運行 3 OpenHands&#xff08;原OpenDevin&#xff09;3.1 簡介3.2 安裝教程和運行 Manus平替開源項目 1 OpenManus 1.1 簡介 開發團隊: MetaGPT 核心貢獻者&#xff08;5…

【Linux 服務之ollama 部署過慢問題】

特別慢的 curl -fsSL https://ollama.com/install.sh | sh參考 方法1 export OLLAMA_MIRROR"https://ghproxy.cn/https://github.com/ollama/ollama/releases/latest/download" curl -fsSL https://ollama.com/install.sh | sed "s|https://ollama.com/downl…

療養院管理系統設計與實現(代碼+數據庫+LW)

摘 要 傳統辦法管理信息首先需要花費的時間比較多&#xff0c;其次數據出錯率比較高&#xff0c;而且對錯誤的數據進行更改也比較困難&#xff0c;最后&#xff0c;檢索數據費事費力。因此&#xff0c;在計算機上安裝療養院管理系統軟件來發揮其高效地信息處理的作用&#xf…

Web后端開發之Maven

Maven Mven是apache旗下的一個開源項目&#xff0c;用來管理和構建java項目的工具。 通過一小段描述信息來管理項目。 Maven的作用 1.依賴管理&#xff1a;方便快捷的管理項目依賴的資源&#xff08;jar包&#xff09;&#xff0c;避免版本沖突問題 以前用某個jar包需要下載…

在線招聘小程序:AI簡歷篩選與精準職位推薦服務

當AI算法遇上小程序開發:重新定義「人崗匹配」的智能招聘革命 一、傳統招聘困境:求職者與企業為何總在「錯過」? 在數字化浪潮下,企業HR日均需處理數百份簡歷,卻仍有60%的崗位因匹配效率低下而空置;求職者海投簡歷后,近八成用戶表示從未收到精準反饋。這種雙向資源錯配…

Linux文件IO——緩沖區磁盤上的文件管理

前言 什么是緩沖區&#xff1f; 緩沖區是內存空間上的一小段內存&#xff0c;我們平常在寫程序的時候&#xff0c;其實是很難感知到緩沖區的存在的&#xff0c;接下來看一段代碼&#xff0c;可以很好地體現緩沖區的存在。 #include<stdio.h> #include<unistd.h> in…

Java中如何去自定義一個類加載器

之前寫過一篇&#xff0c;關于 類加載器和雙親委派的文章&#xff0c;里邊提到過可以根據自己的需要&#xff0c;去寫一個自定義的類加載器&#xff0c;正好有人問這個問題&#xff0c;今天有時間就來手寫一個自定義的類加載器&#xff0c;并使用這個自定義的類加載器來加載一個…

X86 RouterOS 7.18 設置筆記六:端口映射(IPv4、IPv6)及回流問題

X86 j4125 4網口小主機折騰筆記五&#xff1a;PVE安裝ROS RouterOS X86 RouterOS 7.18 設置筆記一&#xff1a;基礎設置 X86 RouterOS 7.18 設置筆記二&#xff1a;網絡基礎設置(IPV4) X86 RouterOS 7.18 設置筆記三&#xff1a;防火墻設置(IPV4) X86 RouterOS 7.18 設置筆記四…

代碼隨想錄|二叉樹|21合并二叉樹

leetcode:617. 合并二叉樹 - 力扣&#xff08;LeetCode&#xff09; 題目 給定兩個二叉樹&#xff0c;想象當你將它們中的一個覆蓋到另一個上時&#xff0c;兩個二叉樹的一些節點便會重疊。 你需要將他們合并為一個新的二叉樹。合并的規則是如果兩個節點重疊&#xff0c;那么…

LDR6500在Type-C轉DP視頻雙向互傳方案

LDR6500在Type-C轉DP視頻雙向互傳方案中扮演著核心角色&#xff0c;以下是對該方案的詳細解析&#xff1a; 一、LDR6500芯片概述 LDR6500是樂得瑞科技針對USB Type-C標準中的Bridge設備而開發的USB-C DRP&#xff08;Dual Role Port&#xff0c;雙角色端口&#xff09;接口USB…

Vue3中 ref 與 reactive區別

ref 用途: ref 通常用于創建一個響應式的基本類型數據&#xff08;如 string、number、boolean 等&#xff09;&#xff0c;但它也可以用于對象或數組 返回值: ref 返回一個帶有 .value 屬性的對象&#xff0c;訪問或修改數據需要通過 .value 進行 使用場景: …

CRM企業客戶關系管理系統產品原型方案

客戶關系管理系統&#xff08;CRM&#xff09;是企業產品應用中的典范&#xff0c;旨在通過信息技術和互聯網技術提升企業核心競爭力&#xff0c;優化企業與顧客在銷售、營銷和服務方面的互動。本作品提供了一套通用型的CRM系統原型模板&#xff0c;涵蓋數據管理、審批流程、統…

【算法】 【c++】字符串s1 中刪除所有 s2 中出現的字符

【算法】 【c】字符串s1 中刪除所有 s2 中出現的字符 eg&#xff1a; s1:“helloworld” s2:“wd” 刪除后&#xff1a;s1:“helloorl” 1 雙循環匹配并刪除–>時間復雜度O(n^2) string 里面的刪除函數–>erase std::string::erase 是 C 標準庫中用于刪除字符串中字符…

利用委托用戶控件、窗體之間傳值 c#

獲取數據方&#xff08;usercontrol111&#xff09;聲明 public Func<Tuple<int, int>> GetCurrentResult { get; set; }獲取數據方調用 var val GetCurrentResult?.Invoke() ?? new Tuple<decimal, decimal>(0, 0);數據發送方聲明與賦值 usercontrol111…