C#中數組、ArrayList和List三者的區別

来源:https://www.cnblogs.com/fsspring/archive/2018/07/31/9395197.html
-Advertisement-
Play Games

[引用BobWei的blog:https://www.cnblogs.com/BObwei/p/4869157.html] 在C#中,ArrayList,List都能夠存儲一組對象,那麼這三者到底有什麼樣的區別呢。 數組 數組在C#中是最早出現的。它在記憶體中是連續的存儲的,所以索引速度很快,而且賦值 ...


[引用BobWei的blog:https://www.cnblogs.com/BObwei/p/4869157.html]

 

在C#中,ArrayList,List都能夠存儲一組對象,那麼這三者到底有什麼樣的區別呢。

 

數組

   數組在C#中是最早出現的。它在記憶體中是連續的存儲的,所以索引速度很快,而且賦值與修改元素也很簡單。可以利用偏移地址訪問元素,時間複雜度為O(1);可以用折半查找法查找元素,效率高。

  

複製代碼
string[] s=new string[3];

//賦值
s[0]="a";
s[1]="b";
s[2]="c";

//修改
s[1]="b1";
複製代碼

 

同時,數組也有很多缺點。數組分配在一塊連續的數據空間上,因此分配空間時必須確定大小。空間的連續,也導致了存儲效率低,插入和刪除元素效率比較低,而且麻煩。如果,要增添一個元素,需要移動大量元素,在記憶體中空出一個元素的空間,然後將要增加的元素放在其中。同樣,你想刪除一個元素,需要移動大量元素去填補被移動的元素。

 

還有我們在聲明數組的時候,必須同時指明數組的長度,數組的長度過長,會造成記憶體浪費,數組和長度過短,會造成數據溢出的錯誤。這樣如果在聲明數組時我們並不清楚數組的長度,就變的很棘手了。

 

針對於數組的這些缺點,C#中最先提供了ArrayList對象來剋服這些缺點。

 

ArrayList

ArrayList是.Net Framework提供的用於數據存儲和檢索的專用類,它是命名空間System.Collections下的一部分。它的大小是按照其中存儲的數據來動態擴充與收縮的。所以,我們在聲明ArrayList對象時並不需要指定它的長度。

 

ArrayList繼承了IList介面,所以它可以很方便的進行數據的添加,插入和移除.比如:

複製代碼
ArrayList list = new ArrayList();

//新增數據
list.Add("abc");
list.Add(123);

//修改數據
list[2] = 345;

//移除數據
list.RemoveAt(0);

//插入數據
list.Insert(0, "hello world");

獲取元素值
object value = al[index]; //al 為 ArrayList 對象,一般需要再對 value 進行類型轉換,比如:int n = (int)value;
設置元素值
al[index] = value; //al 為 ArrayList 對象,index 必須小於 Count
追加元素
int ArrayList.Add(object value) //返回添加的元素的索引
插入元素
void ArrayList.Insert(int index, object value)
刪除元素
刪除元素後,後面的元素會前移,但 Capacity 不會變化。
void ArrayList.Remove(object obj) //從前(索引 0)往後查找,刪除找到的第一個和 obj 相同的元素
void ArrayList.RemoveAt(int index) //刪除索引 index 對應的元素
void ArrayList.RemoveRange(int index, int count) //從索引 index 開始,刪除 count 個元素
查找元素
int ArrayList.IndexOf(object value) //從前(索引 0)往後查找,返回找到的第一個和 obj 相同的元素的索引
int ArrayList.IndexOf(object value, int startIndex)
int ArrayList.IndexOf(object value, int startIndex, int count)
int ArrayList.LastIndexOf(object value) //從後往前(索引 0)查找,返回找到的第一個和 obj 相同的元素的索引
int ArrayList.LastIndexOf(object value, int startIndex)
int ArrayList.LastIndexOf(object value, int startIndex, int count)
複製代碼

從上面示例看,ArrayList好像是解決了數組中所有的缺點,那麼它應該就是完美的了,為什麼在C#2.0後又會出現List呢?

 

還是從上面的示例看,在list中,我們不僅插入了字元串"abc",而且又插入了數字123。這樣在ArrayList中插入不同類型的數據是允許的。因為ArrayList會把所有插入其中的數據都當作為object類型來處理。這樣,在我們使用ArrayList中的數據來處理問題的時候,很可能會報類型不匹配的錯誤,也就是說ArrayList不是類型安全的。既使我們保證在插入數據的時候都很小心,都有插入了同一類型的數據,但在使用的時候,我們也需要將它們轉化為對應的原類型來處理。這就存在了裝箱與拆箱的操作,會帶來很大的性能損耗。

 

穿插一下裝箱與拆箱的概念:

簡單的來講:

裝箱:就是將值類型的數據打包到引用類型的實例中

比如將int類型的值123賦給object對象o

int i=123;
object o=(object)i;

拆箱:就是從引用數據中提取值類型

比如將object對象o的值賦給int類型的變數i

object o=123;
int i=(int)o;

裝箱與拆箱的過程是很損耗性能的。

 

泛型List

 

正是因為ArrayList存在不安全類型與裝箱拆箱的缺點,所以在C#2.0後出現了泛型的概念。而List類是ArrayList類的泛型等效類。它的大部分用法都與ArrayList相似,因為List類也繼承了IList介面。最關鍵的區別在於,在聲明List集合時,我們同時需要為其聲明List集合內數據的對象類型。

複製代碼
List<int> list = new List<int>();
//新增數據
list.Add(123);
//修改數據
list[0] = 345;
//移除數據
list.RemoveAt(0);
複製代碼

上例中,如果我們往List集合中插入string字元"hello world",IDE就會報錯,且不能通過編譯。這樣就避免了前面講的類型安全問題與裝箱拆箱的性能問題了。

複製代碼
Console.WriteLine("List Test:"); 
//聲明一個整型的List 
List<int> lsTest = new List<int>(); 
lsTest.Add(7); 
lsTest.Add(5); 
lsTest.Add(1); 
lsTest.Add(3); 
string strTest=""; 
//list的排序 
lsTest.Sort(); 
//list的遍歷 
foreach(int i in lsTest) 
strTest+=i.ToString()+" "; 
//格式化後輸出 
Console.Write(string.Format("Out:{0} nCount:{1}n",strTest,lsTest.Count)); 
//讀取下一個按鍵,以便讓屏幕顯示數據 
Console.ReadKey();
複製代碼

出結果如下

程式代碼
List Test: 
Out:1 3 5 7 
Count:4

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • zooland 我叫它動物園地,一個構思很長時間的一個項目。起初只是覺得各種通信框架都封裝的很好了,但是就是差些相容,防錯,高可用。同時在使用上,不希望有多餘的代碼,像普通介面一樣使用就可以了。 基於這些想法,看了很多資料,有了很多啟發;也開發出這樣一個版本,而且也在實際項目中應用起來了,算是小有成 ...
  • 日常開發中,經常碰到圖片上傳的需求,尤其在商城系統開發的時候,商品列表商品圖片展示如果使用高清原圖,由於高清原圖比較大,載入原圖時間會大大增加,直接導致系統性能底下,用戶體驗不好,併發量高的時候直接就掛掉了,這時候後臺上傳圖片的時候,就必須將原高清圖進行壓縮,生成高質量縮略圖,然後在商品列表讀取縮略 ...
  • cobbler自動裝機配置如以上所示,謝謝~ ...
  • 一.out的形參變數無需再提前聲明 befor: after: 二.擴展了元組(Tuple的使用,需要Nuget引用 System.ValueTuple) 1.命名的改進: ①.無命名,僅能通過無意義的Item1,Item2進行訪問: befor: after: 混合型命名:(會有一個編譯警告,僅以 ...
  • 簡單的不能再簡單的.net三層實例,只適合剛接觸的菜鳥們看,大神就不要看了。 ...
  • 一、 (Substring);(Remove);(Replace) 1、取字元串的前i個字元 2、去掉字元串的前i個字元 3、從右邊開始取i個字元 4、從右邊開始去掉i個字元 5 、如果字元串中有"abc"則替換成"ABC" 6、c#截取字元串最後一個字元的問題 7、C# 截取字元串最後一個字元 二 ...
  • 1,新建一個窗體MessageForm,在裡面加一個label控制項和timer 2,代碼如下: 3,在其他窗體調用: ...
  • [TOC] 一、前言 在C 學習過程中,多線程一直都是比較難的部分,因為其中涉及到很多與操作系統相關的知識。比如:如何進行多線程編程、線程同步、線程鎖、線程非同步、並行編程、並行集合等等的知識。所以筆者在學習過程中也是遇到了重重困難,而且一直沒有好的教程。 但是筆者在瀏覽GitHub時,發現有大佬已經 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...