数组/集合

数组

一维数组

已知道变量只能包含一个文字值int x = 1;只能为变量x分配一个值。假设要存储100个不同的值,那么创建100个不同的变量将非常麻烦。为了解决这个问题,C#引入了一个数组。数组是一种特殊类型的数据类型,它可以使用特殊语法顺序存储固定数量的值。下图显示了数组如何按顺序存储值。

数组声明

int [] intArr;

数组初始化:可以使用new关键字同时声明和初始化数组,下面三种方式等价

int[] intArr = new int[5]; 

int[] intArr = new int[5]{1, 2, 3, 4, 5};

int[] intArr = {1, 2, 3, 4, 5};

延迟初始化:可以先声明后再初始化数组

string[] strArr, strArr;

strArr = new string[5]{ "1st Element",
                           "2nd Element", 
                           "3rd Element",
                           "4th Element",
                           "5th Element" 
                          };


strArr = new string[]{ "1st Element",
                           "2nd Element",
                           "3rd Element",
                           "4th Element", 
                           "5th Element" 
                          };

可以通过索引访问数组中的元素

intArr[索引位置];

常用属性和方法

方法名称描述
GetLength(int维度) 返回指定维度中的元素数。
GetLowerBound(int维度) 返回指定维度的最低索引。
GetUpperBound(int维度) 返回指定维度的最高索引。
GetValue(int index) 返回指定索引处的值。
属性描述
Length 返回数组中元素的总数。
//数组可以先声明后赋值,也可以声明同时赋值,下面的方式是等价的,数组中必须存储同一类型数据,这在数组被定义时就已经确定
//第一种
int[] intArr = new int[5];
intArr[0] = 1;
intArr[1] = 2;
intArr[2] = 3;
intArr[3] = 4;
intArr[4] = 5;
//第二种
//int[] intArr = new int[5] { 1, 2, 3, 4, 5 };
//第三种
//int[] intArr = { 1, 2, 3, 4, 5 };
//注意这里是维度不是索引
Console.WriteLine("GetLength(int维度):返回指定维度中的元素数,值为:{0}", intArr.GetLength(0));
Console.WriteLine("GetLowerBound(int维度):返回指定维度的最低索引,值为:{0}", intArr.GetLowerBound(0));
Console.WriteLine("GetUpperBound(int维度):返回指定维度的最高索引,值为:{0}", intArr.GetUpperBound(0));
Console.WriteLine("GetValue(int index):    返回指定索引处的值,值为:{0}", intArr.GetValue(2));
Console.WriteLine("属性:Length:返回数组中元素的总数,值为:{0}", intArr.Length);

//使用索引来访问数组元素
Console.WriteLine("使用索引访问数组元素,索引为2的值为:{0}", intArr[2]);
//试图访问数组中不存在的索引元素,会发生数组越界
Console.WriteLine("使用索引访问数组元素,索引为10的值为:{0}", intArr[10]);
for (int i = 0; i < intArr.Length; i++)
{
    Console.WriteLine(intArr[i]);
}
foreach (var item in intArr)
{
    Console.WriteLine(item);
}

多维数组

多维数组,多维数组是像行和列的二维系列,多维数组又称为矩形数组;在本质上,是一个一维数组的列表

//下面的两种创建方式等价
//第一种
//int[,] intArray = { { 1, 1 }, { 1, 2 }, { 1, 3 } };

//第二种
int[,] intArray = new int[3, 4]{//初始化化一个三行四列的数组
                   {0, 1, 2, 3} ,   /*  初始化索引号为 0 的行 */
                   {4, 5, 6, 7} ,   /*  初始化索引号为 1 的行 */
                   {8, 9, 10, 11}   /*  初始化索引号为 2 的行 */
                };
//下面的语句将获取数组中第3行第4个元素                                
Console.WriteLine("二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问,值为:{0}", intArray[2, 3]);
Console.WriteLine("属性:Length:返回数组中元素的总数,值为:{0}", intArray.Length);

可以使用两个索引访问多维数组的值。第一个索引用于行,第二个索引用于列。两个索引都从零开始。

锯齿状数组

锯齿状数组是数组的数组。Jagged数组直接存储数组而不是任何其他数据类型值。锯齿状数组用两个方括号[][]初始化。第一个括号指定数组的大小,第二个括号指定将作为值存储的数组的维度。(锯齿状数组总是存储一个数组),二维数组的大小是矩形的,例如3×3个元素。而锯齿数组的大小设置是比较灵活的,在锯齿数组中,每一行都可以有不同的大小

int[][] intJaggedArray = new int[2][];

intJaggedArray[0] = new int[3]{1,2,3};

intJaggedArray[1] = new int[2]{4,5};

Console.WriteLine(intJaggedArray[0][0]); // 1

Console.WriteLine(intJaggedArray[0][2]); // 3
    
Console.WriteLine(intJaggedArray[1][1]); // 5

Array

.NET提供了一个抽象类Array,作为所有数组的基类。它提供了用于创建,操作,搜索和排序数组的静态方法

常用属性和方法

属性描述
IsFixedSize 获取一个值,该值指示数组是否带有固定大小
IsReadOnly 获取一个值,该值指示数组是否只读
Length 获取一个 32 位整数,该值表示所有维度的数组中的元素总数
LongLength 获取一个 64 位整数,该值表示所有维度的数组中的元素总数
Rank 获取数组的秩(维度)
方法描述
Clear 根据元素的类型,设置数组中某个范围的元素为零、为 false 或者为 null。
Copy(Array, Array, Int32) 从数组的第一个元素开始复制某个范围的元素到另一个数组的第一个元素位置。长度由一个 32 位整数指定。
CopyTo(Array, Int32) 从当前的一维数组中复制所有的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定。
GetLength 获取一个 32 位整数,该值表示指定维度的数组中的元素总数。
GetLongLength 获取一个 64 位整数,该值表示指定维度的数组中的元素总数。
GetLowerBound 获取数组中指定维度的下界。
GetType 获取当前实例的类型。从对象(Object)继承。
GetUpperBound 获取数组中指定维度的上界。
GetValue(Int32) 获取一维数组中指定位置的值。索引由一个 32 位整数指定。
IndexOf(Array, Object) 搜索指定的对象,返回整个一维数组中第一次出现的索引。
Reverse(Array) 逆转整个一维数组中元素的顺序。
SetValue(Object, Int32) 给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定。
Sort(Array) 使用数组的每个元素的 IComparable 实现来排序整个一维数组中的元素。
ToString 返回一个表示当前对象的字符串。从对象(Object)继承。
Array arr = Array.CreateInstance(Type.GetType("System.Int32"), 3);           
arr.SetValue(1, 0);
arr.SetValue(3, 1);
Console.WriteLine("IsFixedSize:取一个值,该值指示数组是否带有固定大小,值为:{0}", arr.IsFixedSize);
Console.WriteLine("IsReadOnly:取一个值,该值指示数组是否只读,值为:{0}", arr.IsReadOnly);
Console.WriteLine("Length:获取一个 32 位整数,该值表示所有维度的数组中的元素总数,值为:{0}", arr.Length);
Console.WriteLine("LongLength:获取一个 64 位整数,该值表示所有维度的数组中的元素总数,值为:{0}", arr.LongLength);
Console.WriteLine("Rank:获取数组的秩(维度),值为:{0}", arr.Rank);
foreach (var item in arr)
{
    Console.WriteLine(item);
}

集合Collections

C#包括在特定系列中包含许多值或对象的专用类,称为“集合”。C#中有两种类型的集合:非泛型集合泛型集合。每个集合类都实现IEnumerable接口,因此可以使用foreach循环访问集合中的值

非泛型集合

System.Collections中命名空间包括以下非泛型集合

类型用法
ArrayList ArrayList存储任何类型的对象,如数组。但是,当数组自动增长时,无需像数组那样指定ArrayList的大小。
SortedList SortedList存储键和值对。它默认按键的升序自动排列元素。C#包括泛型和非泛型SortedList集合。
Stack Stack以LIFO样式存储值(后进先出)。它提供了一个Push()方法来添加一个值,Pop()和Peek()方法来检索值。C#包括通用和非通用堆栈。
Queue 队列以FIFO样式(先进先出)存储值。它保持添加值的顺序。它提供了一个Enqueue()方法来添加值,还提供了一个Dequeue()方法来从集合中检索值。C#包括通用和非通用队列。
Hashtable Hashtable存储键和值对。它通过比较键的哈希值来检索值。
BitArray BitArray管理一个紧凑的位值数组,表示为布尔值,其中true表示该位为on(1),false表示该位为off(0)。
ArrayList

ArrayList是C#中的非泛型类型的集合。它可以包含任何数据类型的元素。它类似于数组,除了它在您添加项目时自动增长。与数组不同,不需要指定ArrayList的大小

要点:

  • ArrayList可以存储任何数据类型的项(元素)
  • 添加元素时,ArrayList会自动调整大小
  • ArrayList可以包含多个null
  • 可以使用foreachfor循环或索引器访问ArrayList

常用属性和方法

属性描述
Capacity 获取或设置ArrayList可以包含的元素数。
Count 获取ArrayList中实际包含的元素数。
IsFixedSize 获取一个值,该值指示ArrayList是否具有固定大小。
IsReadOnly 获取一个值,该值指示ArrayList是否为只读。
Item 获取或设置指定索引处的元素。
方法描述
Add()/AddRange() Add()方法在ArrayList的末尾添加单个元素。 AddRange()方法将指定集合中的所有元素添加到ArrayList中
Insert()/InsertRange() Insert()方法在ArrayList中的指定索引处插入单个元素。 InsertRange()方法从ArrayList中的指定索引开始插入指定collection的所有元素。
Remove()/RemoveRange() Remove()方法从ArrayList中删除指定的元素。 RemoveRange()方法从ArrayList中删除一系列元素。
RemoveAt() 从ArrayList中删除指定索引处的元素。
Sort() 对ArrayList的整个元素进行排序。
Reverse() 反转整个ArrayList中元素的顺序。
Contains 检查ArrayList中是否存在指定的元素。如果存在则返回true,否则返回false。
Clear 删除ArrayList中的所有元素。
CopyTo 将所有元素或元素范围复制到compitible Array。
GetRange 从ArrayList返回指定索引中指定数量的元素。
IndexOf 搜索指定的元素并返回零基索引(如果找到)。如果找不到元素,则返回-1。
ToArray 从ArrayList返回compitible数组。
ArrayList arrayList = new ArrayList();
arrayList.Add("wang");
arrayList.Add(1);
//ArrayList允许插入null
arrayList.Add(null);

foreach (var item in arrayList)
{
    Console.WriteLine(item);
}
SortedList

SortedList集合默认按键的升序存储键值对。SortedList类实现IDictionaryICollection接口,因此可以通过键和索引访问元素。C#包括两种类型的SortedList,泛型SortedList和非泛型SortedList。先了解非泛型SortedList

要点:

  • C#具有泛型和非泛型SortedList
  • SortedList按键的升序存储键值对。键必须是唯一的,不能为null,而值可以为null或重复
  • 非泛型SortedList存储任何数据类型的键和值。因此,需要将值转换为适当的数据类型
  • 键值对可以强制转换为DictionaryEntry
  • 使用索引器访问单个值。SortedList索引器接受键以返回与之关联的值

常用属性和方法

属性描述
Capacity 获取或设置SortedList实例可以存储的元素数。
Count 获取SortedList中实际包含的元素数。
IsFixedSize 获取SortedList中实际包含的元素数。
IsReadOnly 获取一个值,该值指示SortedList是否为只读。
Item 获取或设置SortedList中指定键的元素。
Keys 获取SortedList的键列表。
Values 获取SortedList中的值列表。
方法描述
Add(object key, object value) 将键值对添加到SortedList中
Remove(object key) 删除具有指定键的元素
RemoveAt(int index) 删除指定索引处的元素
Contains(object key) 检查SortedList中是否存在指定的键
Clear() 从SortedList中删除所有元素
GetByIndex(int index) 返回存储在内部数组中的索引值
GetKey(int index) 检返回存储在内部数组中指定索引处的键
IndexOfKey(object key) 返回存储在内部数组中的指定键的索引
IndexOfValue(object value) 返回存储在内部数组中的指定值的索引
SortedList sortedList = new SortedList();
sortedList.Add(2, "wang");
sortedList.Add(5, "li");
sortedList.Add(3, 5);
//SortedList键可以是任何数据类型,但不能在同一SortedList中添加不同数据类型的键。
sortedList.Add("wang", 32);

for (int i = 0; i < sortedList.Count; i++)
{
    Console.WriteLine("key:{0},value:{1}", sortedList.GetKey(i), sortedList.GetByIndex(i));
}

foreach (DictionaryEntry item in sortedList)
{
    Console.WriteLine("key:{0},value:{1}", item.Key, item.Value);
}
Stack

C#包含一种特殊类型的集合,它以LIFO样式存储元素(后进先出)。C#包括通用和非通用堆栈,非泛型堆栈。Stack允许空值以及重复值。它提供了一个Push()方法来添加一个值,Pop()Peek()方法来检索值。

要点:

  • Stack将值存储在LIFO(后进先出)样式中。最后添加的元素将是首先出现的元素。
  • 使用Push()方法将元素添加到Stack中。
  • Pop()方法返回并从堆栈顶部删除元素。在空Stack上调用Pop()方法将引发异常。
  • Peek()方法总是返回Stack中最顶层的元素。

常用属性和方法

属性描述
Count 返回Stack中元素的总数。
方法描述
Push 在堆栈顶部插入一个项目。
Peek 返回堆栈中的顶部项。
Pop 从堆栈顶部删除并返回项目。
Contains 检查堆栈中是否存在项目。
Clear 从堆栈中删除所有项目。
Stack stack = new Stack();
stack.Push("1");
stack.Push(1);
stack.Push(false);

foreach (var item in stack)
{
    Console.WriteLine(item);
}
Queue

C#包含System.Collection命名空间中的Queue集合类。队列以FIFO样式(先进先出)存储元素,与Stack集合完全相反。它按照添加顺序包含元素。队列集合允许多个空值和重复值。使用Enqueue()方法添加值,使用Dequeue()方法从队列中检索值。

要点:

  • 队列将值存储在FIFO(先进先出)样式中。首先添加的元素将首先出现。
  • 使用Enqueue()方法将元素添加到Queue中
  • Dequeue()方法返回并从队列的开头删除元素。在空队列上调用Dequeue()方法将引发异常。
  • Peek()方法总是返回最顶层的元素。

常用属性和方法

属性描述
Count 返回Stack中元素的总数。
方法描述
Enqueue 将项添加到队列中。
Dequeue 从队列的开头删除并返回一个项目。
Peek 返回队列中的第一个项目
Contains 检查项目是否在队列中
Clear 从队列中删除所有项目。
TrimToSize 将队列的容量设置为队列中的实际项目数。
Queue queue = new Queue();
queue.Enqueue("1");
queue.Enqueue(1);
queue.Enqueue(false);

foreach (var item in queue)
{
    Console.WriteLine(item);
}
Hashtable

C#包含System.Collections命名空间中的Hashtable集合,类似于通用字典集合。Hashtable集合存储键值对。它通过计算每个密钥的哈希码来优化查找,并在内部将其存储在不同的存储桶中,然后在访问值时匹配指定密钥的哈希码。

要点:

  • Hashtable存储Key必须唯一的任何数据类型的键值对
  • Hashtable键不能为null,而值可以为null
  • Hashtable通过比较键的哈希码来检索项目。因此它的性能比Dictionary集合慢
  • Hashtable使用默认的哈希码提供程序,即object.GetHash()。您还可以使用自定义哈希码提供程序。
  • DictionaryEntryforeach语句一起使用以迭代Hashtable

Hashtable的重要属性和方法:

属性描述
Count 获取Hashtable中键/值对的总数。
IsReadOnly 获取布尔值,指示Hashtable是否为只读。
Item 获取或设置与指定键关联的值。
Keys 获取Hashtable中的键的ICollection。
Values 获取Hashtable中值的ICollection。
方法描述
Add 将具有键和值的项添加到哈希表中
Remove 从散列表中删除具有指定键的项。
Clear 从哈希表中删除所有项目。
Contains 检查哈希表是否包含特定密钥。
ContainsKey 检查哈希表是否包含特定密钥。
ContainsValue 检查哈希表是否包含特定值。
GetHash 返回指定键的哈希码。
Hashtable hashtable = new Hashtable();
hashtable.Add(1, "wang");
hashtable.Add(3, false);
hashtable.Add(2, "li");

foreach (DictionaryEntry item in hashtable)
{
    Console.WriteLine("key:{0}, value:{1}", item.Key, item.Value);
}
BitArray

BitArray 类管理一个紧凑型的位值数组,它使用布尔值来表示,其中true表示位是开启的(1),false 表示位是关闭的(0)。当需要存储位,但是事先不知道位数时,则使用点阵列。可以使用整型索引从点阵列集合中访问各项,索引从零开始。

BitArray的重要属性和方法:

属性描述
Count 获取 BitArray 中包含的元素个数。
IsReadOnly 获取一个值,表示 BitArray 是否只读。
Item 获取或设置 BitArray 中指定位置的位的值。
Length 获取或设置 BitArray 中的元素个数。
方法描述
public BitArray And( BitArray value ); 对当前的 BitArray 中的元素和指定的 BitArray 中的相对应的元素执行按位与操作。
public bool Get( int index ); 获取 BitArray 中指定位置的位的值。
public BitArray Not(); 把当前的 BitArray 中的位值反转,以便设置为 true 的元素变为 false,设置为 false 的元素变为 true。
public BitArray Or( BitArray value ); 对当前的 BitArray 中的元素和指定的 BitArray 中的相对应的元素执行按位或操作。
public void Set( int index, bool value ); 把 BitArray 中指定位置的位设置为指定的值。
public void SetAll( bool value ); 把 BitArray 中的所有位设置为指定的值。
public BitArray Xor( BitArray value ); 对当前的 BitArray 中的元素和指定的 BitArray 中的相对应的元素执行按位异或操作。

泛型集合

同传统的集合相比,泛型集合是一种强类型的集合,它解决了类型安全问题,同时避免了集合中每次的装箱与拆箱的操作,提升了性能

List<T>

List<T>在C#应用程序中是一种快捷、易于使用的泛型集合类型,使用泛型编程为编写面向对象程序增加了极大的效率和灵活性,不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换

常用方法:

名称描述
Add 将对象添加到 List 的结尾处
AddRange 将指定集合的元素添加到 List 的末尾
AsReadOnly 返回当前集合的只读 IList 包装
BinarySearch(T) 使用默认的比较器在整个已排序的 List 中搜索元素,并返回该元素从零开始的索引。
BinarySearch(T, IComparer) 使用指定的比较器在整个已排序的 List 中搜索元素,并返回该元素从零开始的索引。
BinarySearch(Int32, Int32, T, IComparer) 使用指定的比较器在已排序 List 的某个元素范围中搜索元素,并返回该元素从零开始的索引。
Clear 从 List 中移除所有元素。
Contains 确定某元素是否在 List 中。
ConvertAll 将当前 List 中的元素转换为另一种类型,并返回包含转换后的元素的列表。
CopyTo(T[]) 将整个 List 复制到兼容的一维数组中,从目标数组的开头开始放置。
Exists 确定 List 是否包含与指定谓词所定义的条件相匹配的元素。
Find 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的第一个匹配 元素。
FindIndex(Predicate) 搜索与指定谓词所定义的条件相匹配的元素,并返回整个List 中第一个匹配元素的从零开始的索引。
ForEach 对 List 的每个元素执行指定操作。 GetEnumerator 返回循环访问 List 的枚举器。
IndexOf(T) 搜索指定的对象,并返回整个 List 中第一个匹配项的从零开始的索引。
Insert 将元素插入 List 的指定索引处。
InsertRange 将集合中的某个元素插入 List 的指定索引处。
LastIndexOf(T) 搜索指定的对象,并返回整个 List 中最后一个匹配项的从零开始的索引。
Remove 从 List 中移除特定对象的第一个匹配项。
Reverse() 将整个 List 中元素的顺序反转。
Sort() 使用默认比较器对整个 List 中的元素进行排序。
List<int> intList = new List<int>();
intList.Add(3);
intList.Add(54);
intList.Add(14);
foreach (var item in intList)
{
    Console.WriteLine(item);
}
Stack<T>

类以后进先出的方式维护数据的集合,包含pop()和push(),从栈内压入或移除数据

Quenue<T>

队列以先进先出的方式访问数据,使用Enqueue()和Dequeue()添加数据和移除数据

SortedSet<T>

这个类中的数据是排序的,在插入和移除数据之后仍然能自动排序,需要向其构造函数中传递一个实现了IComparer,该接口定义了Compare方法。

ObservableCollection<T>

类表示能在添加、移除或者刷新整个列表时提供通知的动态数据集,合,ReadOnlyObservableCollection的操作与之类似,不过是只读的。ObservableCollection实现了一个名为CollectionChanged事件,该事件在插入新的数据或者移除数据时触发

Dictionary<k,v>

Dictionary提供快速的基于键值的元素查找。结构是:Dictionary <[key] , [value]>,当你有很多元素的时候可以用它。在使用前,你必须声明它的键类型和值类型

数组、ArrayList和List三者的区别

  • 数组:针对特定类型固定长度,值不可为null,在声明数组的时候必须指定数组的长度,可有多个维度
  • Array:数组的另一种创建方式,抽象类Array,作为所有数组的基类,针对任意类型固定长度,值可以为null,输出会被替换为0
  • ArrayList:针对任意类型、任意长度的,值可以为null,存储或检索值类型时通常发生装箱和取消装箱操作,带来很大的性能耗损
  • List:强类型的集合,固定类型、任意长度,值不可为null,是类型安全的,

索引器(Indexer)

Indexer是一种特殊类型的属性,允许以与其内部集合的数组相同的方式访问类或结构。除了使用带有方括号和参数的此关键字定义的属性外,它与属性相同。
要点:

  • 索引器与属性相同,除了它使用带有方括号的此关键字定义,该参数具有参数。
  • 可以通过具有不同类型的参数来覆盖索引器。
  • 不支持使用索引器的Refout参数。
  • 索引器可以作为接口成员包含在内。

语法

Public <return type> this[<parameter type> index]
{
    Get{
    // return the value from the specified index
    }
    Set{
    // set values at the specified index
    }
}
public class Indexer
{
        private int[] indexs = new int[10];

        public int this[int index]
        {
            get { return indexs[index]; }
            set
            {
                indexs[index] = value;
            }
        }
}
/*
Indexer是一种特殊类型的属性,允许以与其内部集合的数组相同的方式访问类或结构。
除了使用带有方括号和参数的此关键字定义的属性外,它与属性相同。
*/
Console.WriteLine("********************索引器*********************");

Indexer indexer = new Indexer();
indexer[0] = 1;
indexer[1] = 2;
Console.WriteLine(indexer[1]);
原文地址:https://www.cnblogs.com/GnailGnepGnaw/p/10618666.html