詳解c#中Array,ArrayList與List<T>的區(qū)別、共性與相互轉(zhuǎn)換
Array,ArrayList and List<T>
Array、ArrayList和List都是從IList派生出來的,它們都實現(xiàn)了IEnumerable接口
從某種意義上來說,ArrayList和List屬于集合的范疇,因為他們都來自程序集System.Collections
,但是因為它們都是儲存了多個變量的數(shù)據(jù)結(jié)構(gòu),并且都不是類似鍵值對的組合,并且沒有先進先出或者先進后出的機制,故而稱為數(shù)組。
我們一般稱呼Array
,ArrayList
and List<T>
為數(shù)組。
Array
Array必須在定義且不初始化賦值的時候(不初始化的情況下聲明數(shù)組變量除外)必須定義數(shù)組最外側(cè)的長度。比如:
int[] vs = new int[10]; int[,] duoWei = new int[3, 4]; int[][] jiaoCuo = new int[3][]; // 該數(shù)組是由三個一維數(shù)組組成的
一維數(shù)組
定義
用類似于這種方式定義一個數(shù)組
int[] array = new int[5];
初始化賦值
用類似于這種方式初始化
int[] array1 = new int[] { 1, 3, 5, 7, 9 };
也可以進行隱式初始化
int[] array2 = { 1, 3, 5, 7, 9 }; string[] weekDays2 = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
用類似于下面這種方式先聲明,再賦值
int[] array3; array3 = new int[] { 1, 3, 5, 7, 9 }; // OK //array3 = {1, 3, 5, 7, 9}; // Error
多維數(shù)組
數(shù)組可具有多個維度。多維數(shù)組的每個元素是聲明時的數(shù)組所屬類型的元素。比如說int[,]
的每個元素都是int類型而不是int[]類型。換種說法就是多維數(shù)組不能算做“數(shù)組組成的數(shù)組”。
定義
用類似下面這種方式聲明一個二維數(shù)組的長度
int[,] array = new int[4, 2];
初始化賦值
用類似于下面的方式初始化多維數(shù)組:
// Two-dimensional array. int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // The same array with dimensions specified. int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // A similar array with string elements. string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" }, { "five", "six" } }; // Three-dimensional array. int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };
還可在不指定級別的情況下初始化數(shù)組
int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
不初始化的情況下聲明數(shù)組變量:
int[,] array5; array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // OK //array5 = {{1,2}, {3,4}, {5,6}, {7,8}}; // Error
元素賦值和獲取元素
可以用類似于array[1,2]
的方式來獲取數(shù)組的值和為數(shù)組賦值。
GetLength(0)
可以獲取最外圍數(shù)組的長度,GetLength(1)
可以獲得第二層數(shù)組的長度。以此類推。為一個二維數(shù)組duoWei
循環(huán)賦值的方式如下:
Console.WriteLine("二維數(shù)組賦值"); for (int i = 0; i < duoWei.GetLength(0); i++) { for (int j = 0; j < duoWei.GetLength(1); j++) { duoWei[i, j] = i + j; } }
如何獲取二維數(shù)組中的元素個數(shù)呢?
int[,] array = new int[,] {{1,2,3},{4,5,6},{7,8,9}};//定義一個3行3列的二維數(shù)組 int row = array.Rank;//獲取維數(shù),這里指行數(shù) int col = array.GetLength(1);//獲取指定維度中的元素個數(shù),這里也就是列數(shù)了。(0是第一維,1表示的是第二維) int col = array.GetUpperBound(0)+1;//獲取指定維度的索引上限,在加上一個1就是總數(shù),這里表示二維數(shù)組的行數(shù) int num = array.Length;//獲取整個二維數(shù)組的長度,即所有元的個數(shù)來源:C#中如何獲取一個二維數(shù)組的兩維長度,即行數(shù)和列數(shù)?以及多維數(shù)組各個維度的長度?
交錯數(shù)組
交錯數(shù)組是一個數(shù)組,其元素是數(shù)組,大小可能不同。 交錯數(shù)組有時稱為“數(shù)組的數(shù)組”。
交錯數(shù)組不初始化就聲明的方式如下:
int[][] ccf; ccf = new int[3][];
交錯數(shù)組類似于python的多維數(shù)組,比較符合人類的直覺,一個交錯數(shù)組里面包含了多個數(shù)組。
定義
可以采用類似下面的方式來聲明一個交錯數(shù)組:
// 定義多維數(shù)組要求每個維度的長度都相同 下面定義交錯數(shù)組 int[][] jiaoCuo = new int[3][]; // 該數(shù)組是由三個一維數(shù)組組成的
上面聲明的數(shù)組是具有三個元素的一維數(shù)組,其中每個元素都是一維整數(shù)數(shù)組。
可使用初始化表達式通過值來填充數(shù)組元素,這種情況下不需要數(shù)組大小。 例如:
jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 }; jaggedArray[1] = new int[] { 0, 2, 4, 6 }; jaggedArray[2] = new int[] { 11, 22 };
初始化賦值
可在聲明數(shù)組時將其初始化,如:
int[][] jaggedArray2 = new int[][] { new int[] { 1, 3, 5, 7, 9 }, new int[] { 0, 2, 4, 6 }, new int[] { 11, 22 } };
獲取元素和單個賦值
可以用類似于jiaoCuo[1][1]
來獲取單個元素的值,也可以用類似于jiaoCuo[1][1] = 2;
來為單個元素賦值。
可以采取類似于下面的方式來進行循環(huán)賦值:
Console.WriteLine("交錯數(shù)組循環(huán)賦值"); // 先聲明交錯數(shù)組中每一個數(shù)組的長度 for (int i = 0; i < 3; i++) { jiaoCuo[i] = new int[i + 1]; } // 然后對交錯數(shù)組中的每一個元素賦值 for (int i = 0; i < jiaoCuo.Length; i++) { Console.WriteLine($"交錯數(shù)組的第{i + 1}層"); for (int j = 0; j < jiaoCuo[i].Length; j++) { jiaoCuo[i][j] = i + j; Console.WriteLine(jiaoCuo[i][j]); } }
方法和屬性
像數(shù)組這種儲存多個變量的數(shù)據(jù)結(jié)構(gòu),最重要的就是增查刪改、獲取長度和數(shù)據(jù)類型轉(zhuǎn)換。Array因為數(shù)組的特性,長度不可改變,所以增查刪改只能有查和改。
改
Array類型用用類似于下面的方式進行改操作:
vs[0] = 12; //一維數(shù)組 duoWei[1, 2] = 3; //多維數(shù)組 jiaoCuo[1][1] = 2; //交錯數(shù)組
查
Array類型用類似于下面的方式進行查操作:
int[] vs = new int[10]; vs[0] = 12; Console.WriteLine(Array.IndexOf(vs, 12)); //0 Console.WriteLine(vs.Contains(12)); // True
獲取長度
可以用類似于下面這種方式來獲?。?/p>
Console.WriteLine(vs.Length); Console.WriteLine(vs.Count());
交錯數(shù)組的Length
是獲取所包含數(shù)組的個數(shù),多維數(shù)組的Length
是獲取數(shù)組的元素的總個數(shù),多維數(shù)組GetLength(0)
可以獲取最外圍數(shù)組的長度,GetLength(1)
可以獲得第二層數(shù)組的長度。以此類推。
Array.ConvertAll() 數(shù)據(jù)類型轉(zhuǎn)換
可以用Array.ConvertAll<TInput,TOutput>(TInput[], Converter<TInput,TOutput>)
來進行數(shù)組類型的轉(zhuǎn)換。
參數(shù)如下:
- array
TInput[]要轉(zhuǎn)換為目標類型的從零開始的一維 Array。
- converter
Converter用于將每個元素從一種類型轉(zhuǎn)換為另一種類型的 Converter。
來源:[Array.ConvertAll(TInput], Converter) 方法 (System) | Microsoft Docs
demo如下:
double[] vs3 = Array.ConvertAll(vs, item => (double)item);
切片
默認狀態(tài)下只能對一維數(shù)組進行切片,或者通過交錯數(shù)組獲取的一維數(shù)組也可以進行切片。
切片的方式類似于vs[1..5]
,表示vs數(shù)組從1到5,左閉右開。^1表示-1,即最后一個元素。[^3..^1]
表示倒數(shù)第三個元素到倒數(shù)第一個元素,左閉右開。
獲取單個元素和賦值
可以采用下面的方式來獲取單個元素和為單個元素單獨賦值:
// 一維數(shù)組 Console.WriteLine(vs[1]); vs[1] = 2; // 多維數(shù)組 Console.WriteLine(duoWei[1, 2]); duoWei[1, 2] = 3; // 交錯數(shù)組 Console.WriteLine(jiaoCuo[1][0]); jiaoCuo[1][0] = 0;
Array.ForEach 循環(huán)
System.Array里面也有ForEach方法,這是用于Array的。
demo:
Array.ForEach(vs, item => Console.WriteLine(item));
ArrayList
定義
用類似于下面的三種方式中的任意一種來聲明ArrayList:
ArrayList() | 初始化 ArrayList 類的新實例,該實例為空并且具有默認初始容量。 |
---|---|
ArrayList(ICollection) | 初始化 ArrayList 類的新實例,該類包含從指定集合復(fù)制的元素,并具有與復(fù)制的元素數(shù)相同的初始容量。 |
ArrayList(Int32) | 初始化 ArrayList 類的新實例,該實例為空并且具有指定的初始容量。 |
可以將Arraylist看作是一種長度可以自由變換,可以包含不同數(shù)據(jù)類型元素的數(shù)組。
初始化賦值
可以采用類似于下面的方式來初始化賦值:
ArrayList arrayList1 = new ArrayList() { 12, 334, 3, true };
循環(huán)
循環(huán)可以用for和foreach。
foreach (var item in arrayList) { Console.WriteLine(item); }
方法和屬性
和list<T>
類似,但是沒有ConvertAll
方法。ArrayList本身沒有ForEach方法,但是也可以用傳統(tǒng)的foreach方法(就像前面提到的ArrayList的循環(huán)那樣)。
具體的方法和屬性請查看List
List<T>
定義
用類似于下面的三種方式中的任意一種來聲明List<T>
:
List() | 初始化 List 類的新實例,該實例為空并且具有默認初始容量。 |
---|---|
List(IEnumerable) | 初始化 List 類的新實例,該實例包含從指定集合復(fù)制的元素并且具有足夠的容量來容納所復(fù)制的元素。 |
List(Int32) | 初始化 List 類的新實例,該實例為空并且具有指定的初始容量。 |
初始化
用類似于下面的方式在聲明時初始化:
List<string> listA = new List<string>() { "hello", " ", "wrold" };
循環(huán)
List<T>
有一個名稱為ForEach
的方法:
public void ForEach (Action<T> action);
該方法的本質(zhì)是要對 List 的每個元素執(zhí)行的 Action 委托。Action 的參數(shù)即為List<T>
在循環(huán)過程中的每個元素。
demo如下:
// 聲明 List<string> listA = new List<string>() { "hello", " ", "wrold" }; // 循環(huán) var i = 0; listA.ForEach(item => { Console.WriteLine($"第{i + 1}個"); Console.WriteLine(item); i++; });
方法和屬性
從獲取長度、增查刪改、數(shù)據(jù)類型轉(zhuǎn)換、切片和循環(huán)來解析。其中除了數(shù)據(jù)類型轉(zhuǎn)換和List<T>
類型本身就擁有的ForEach方法外,都適用于ArrayList。
先聲明一個List<string>
作為演示的基礎(chǔ):
List<string> listA = new List<string>() { "hello", " ", "wrold" };
屬性 長度
Count屬性可以獲取長度
Console.WriteLine(listA.Count);
屬性 取值
Console.WriteLine(listA[0]);
增
即增加元素,可以用Add方法:
listA.Add("12");
查
IndexOf獲取所在位置,Contains獲取是否包含。
Console.WriteLine(listA.IndexOf("12")); Console.WriteLine(listA.Contains("12"));
刪
Remove根據(jù)數(shù)據(jù)刪除,RemoveAt根據(jù)位置刪除。
listA.Remove("12"); listA.RemoveAt(1);
改
可以用類似于listA[1] = "改變";
的方式來修改元素內(nèi)容。
切片
可以用GetRange(int index, int count)
來進行切片操作,第一個參數(shù)是切片開始的位置,第二個參數(shù)是切片的數(shù)量,即從index開始往后數(shù)幾個數(shù)。
Console.WriteLine(listA.GetRange(1, 1).Count);
循環(huán)
List<T>
有一個名稱為ForEach
的方法,該方法的本質(zhì)是要對 List 的每個元素執(zhí)行的 Action 委托。Action 的參數(shù)即為List<T>
在循環(huán)過程中的每個元素。
demo如下:
// 聲明 List<string> listA = new List<string>() { "hello", " ", "wrold" }; // 循環(huán) var i = 0; listA.ForEach(item => { Console.WriteLine($"第{i + 1}個"); Console.WriteLine(item); i++; });
數(shù)據(jù)類型轉(zhuǎn)換
可以用ConvertAll來對數(shù)組的數(shù)據(jù)類型進行轉(zhuǎn)換,這是List<T>
自帶的方法。System.Array里面也有ConvertAll方法,這是用于Array的。
List<object> listObject = listA.ConvertAll(s => (object)s);
區(qū)別
成員單一類型 | 長度可變 | 切片友好 | 方法豐富 | 增查刪改 | ConvertAll | |
---|---|---|---|---|---|---|
一維數(shù)組 | ? | ? | ? | ? | 查、改 | ? |
多維數(shù)組 | ? | ? | ? | ? | 查、改 | ? |
交錯數(shù)組 | ? | ? | ? | ? | 查、改 | ? |
ArrayList | ? | ? | ? | ? | 增查刪改 | ? |
List<T> |
? | ? | ? | ? | 增查刪改 | ? |
Array最大的好處就是切片友好,可以使用類似于[1..3]
的方式切片,這是比GetRange
更加直觀的切片方式。List<T>
類型可以通過ToArray的方法來轉(zhuǎn)變成Array。
Array,ArrayList and List<T>之間的轉(zhuǎn)換
關(guān)于這一部分的demo代碼詳情可從Array,ArrayList and List之間的轉(zhuǎn)換 · sogeisetsu/Solution1@88f27d6 (github.com)獲得。
先分別聲明這三種數(shù)據(jù)類型。
// 聲明數(shù)組 int[] a = new int[] { 1,3,4,5,656,-1 }; // 聲明多維數(shù)組 int[,] aD = new int[,] { { 1, 2 }, { 3, 4 } }; // 聲明交錯數(shù)組 int[][] aJ = new int[][] { new int[]{ 1,2,3}, new int[]{ 1} }; // 聲明ArrayList ArrayList b = new ArrayList() { 1, 2, 344, "233", true }; // 聲明List<T> List<int> c = new List<int>();
Array轉(zhuǎn)ArrayList
// 數(shù)組轉(zhuǎn)ArrayList ArrayList aToArrayList = new ArrayList(a);
Array轉(zhuǎn)List<T>
List<int> aToList = new List<int>(a); List<int> aToLista = a.ToList();
List<T>轉(zhuǎn)Array
int[] cToList = c.ToArray();
List<T>轉(zhuǎn)ArrayList
ArrayList cToArrayList = new ArrayList(c);
ArrayList轉(zhuǎn)Array
// ArrayList轉(zhuǎn)Array object[] bToArray = b.ToArray();
在轉(zhuǎn)換的過程中,會丟失數(shù)據(jù)類型的準確度,簡單來說就是轉(zhuǎn)換成的Array會變成object
這種轉(zhuǎn)換的意義不大,如果轉(zhuǎn)換完之后再強行用Array.ConvertAll方法來進行數(shù)據(jù)類型的轉(zhuǎn)換,很有可能會出現(xiàn)諸如Unable to cast object of type 'System.String' to type 'System.Int32'.
的錯誤,這是因為ArrayList本身成員就可以不是單一類型。
數(shù)組的打印
Array的打印
對于Array的打印,我找到了四種方式,如下:
調(diào)用Array.ForEach
Array.ForEach(a, item => Console.WriteLine(item));
傳統(tǒng)forEach
foreach (var item in a) { Console.WriteLine(item); }
傳統(tǒng)for
for (int i = 0; i < a.Count(); i++) { Console.WriteLine(a[i]); }
string.Join
Console.WriteLine(string.Join("\t", a));
ArrayList的打印
ArrayList的打印我知道的就只有傳統(tǒng)的for和foreach兩種方式。
List<T>的打印
List<T>
的打印除了傳統(tǒng)的for和foreach兩種方式之外,還有List<T>
本身自帶的foreach:
var i = 0; listA.ForEach(item => { Console.WriteLine($"第{i + 1}個"); Console.WriteLine(item); i++; });
請注意:ArrayList和List<T>
均沒有string.Join
和調(diào)用Array.ForEach
兩種方式來打印數(shù)組。
到此這篇關(guān)于詳解c#中Array,ArrayList與List<T>的區(qū)別、共性與相互轉(zhuǎn)換的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#中用foreach語句遍歷數(shù)組及將數(shù)組作為參數(shù)的用法
這篇文章主要介紹了C#中用foreach語句遍歷數(shù)組及將數(shù)組作為參數(shù)的用法,C#的數(shù)組可作為實參傳遞給方法形參,需要的朋友可以參考下2016-01-01C#實現(xiàn)將javascript文件編譯成dll文件的方法
這篇文章主要介紹了C#實現(xiàn)將javascript文件編譯成dll文件的方法,涉及C#編譯生成dll動態(tài)鏈接庫文件的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11