c#中的类数组数据集合

列表

列表是和数组最像的结构了。使用int索引获取和访问值。但是列表的容量是可变的。

int[] arr = { 1,2,3};
List<int> list = new List<int>(arr);
List<int> list2 = new List<int>();

构造器中使用一个序列,会直接复刻那种序列的状态。

访问元素

列表可以像数组一样使用索引器访问和修改元素。

list[0] = 20;
int b = list[1];
list[2]++;

改变容量

列表的改变容量必须和添加/删除元素同时进行。

在末尾添加元素

list.Add(1);
list.AddRange(arr);

AddRange可以一次性添加一整个序列的元素。

在中间插入元素

list.Insert(1,20);
list.InsertRange(1,arr);

第一个参数是int类型,表示索引。第二个参数是泛型参数的类型,或他的序列。
插入的数据会占据填入的索引,之后的元素全部向后顺位。

删除一个元素

list.Remove(1);
list.RemoveAt(1);

Remove是查找相等的元素,在这里也就是删除等于1的元素。
如果有多个相等的元素,只会删除查找到的第一个元素。
会返回一个bool值,指示是否真的删除了元素(查找到了相等的元素)。

RemoveAt是删除指定索引处的元素。

删除多个元素

list.RemoveRange(3, 2);
list.RemoveAll(i => i == 20);

现在c#的范围运算还没有普及开来。
大部分牵扯到范围的事,都是开始索引+往后连续的长度。
比如这里的RemoveRange(3, 2),就是指从索引3开始数,数两个数。也就是删除掉索引为3,4的值。

RemoveAll则是一个委托,删除所有符合条件的值。

列表的数组管理

大多数数据集合都是在背后有一个数组存放数据的。
因为数组这种最基本的数据结构比较省空间,而且找的快。

如果添加元素时,长度不够了,那么会建立一个新数组,把旧值复制进去。
如果长度过长,那么就会浪费一堆空间。

如何增长

如果没有设置初始长度,会以0为基础值,也就是不声明数组。在添加内容后,初始声明长度为4的数组。
如果构造器填入序列或一个数量,那么长度和序列长度或参数一致。

在超出大小后,会声明当前长度*2的数组。

设置长度

使用Capacity属性可以获得或调整数组长度。当然如果长度比需要的长度还小会报错。
TrimExcess方法在所需长度少于数组长度90%时,把数组长度设置为和所需长度一致。

清空

Clear方法会清空元素,但是保留背后的数组。
想较而言如果直接新建一个List,要重新配置数组。

其他方法

排序

List的排序方法直接从实例上调用。
甚至如果他无法排序,还可以使用一个委托,指定如何排序。

class Student
{
    public string name;
    public int age;
    public int id;
}
Student[] stArr = new Student[]
         {
             new() { name = "小明", age = 12 ,id=1 },
             new() { name = "小红", age = 13 ,id=2 },
             new() { name = "小丽", age = 12 ,id=3 }
         };
List<Student> list = new List<Student>(stArr);
list.Sort();
list.Sort((a, b) => a.id - b.id);

这个委托有两个参数,指代比较的两个元素。
返回结果是一个整数,如果小于0,则第一个参数排在第二个参数前面。
如果大于0,则排在后面。
如果等于0,他们并列。但是c#使用的排序方法是不稳定的排序,并列的元素在排序后无法预测谁在前面。

反转

Reverse方法。和LINQ一样,不过会对自己身上生效。

存在

Exists方法,等同LINQ的Any方法,填入一个委托,查看是否有满足条件的元素

全匹配

TrueForAll方法,等同LINQ的All方法,填入一个委托,查看元素是否全部满足条件。

搜索索引

IndexOf方法,一个参数

字典

字典也使用索引访问内容。但索引不要求数字,可以是任何类型。
因此也不带顺序。例如如果你使用数字做索引,那么可以凭空出现索引10,而0-9都没有。

class Student
{
    public string name;
    public int age;
}
Dictionary<string, Student> dic = new Dictionary<string, Student>();

第一个泛型是键(Key)类型,充当索引类型。
第二个泛型是值(Value)类型,通过索引访问的类型。

添加和更新元素

dic["小明"] = new Student() { name = "小明", age = 12 };
dic["小红"] = null;

使用索引指定新值,可以添加或更新元素。
索引不能是null,虽然写起来不会报错,但运行的时候会报错。

一个弊端是,有时候不希望在已经存在值的时候去更改值。
可以使用TryAdd方法尝试添加值,如果这个索引已经存在,那么无事发生。

dic.TryAdd("小明", null);

这个方法会返回一个bool值,指示是否添加成功(是否找到相同索引)。
索引和值必须成对出现,所以这个方法需要两个参数。

访问元素

使用索引也可以访问元素

Console.WriteLine(dic["小明"].name);
Student st = dic["小红"];

前提是字典已经收录过这个索引。如果没有那么会报错。

如果你无法确定是否存在这个索引,可以使用TryGetValue方法尝试获取值。

dic.TryGetValue("小绿", out Student st2); 

输出值以out参数形式输出。方法自己的返回值是bool,指示是否成功找到值。
如果没有找到,输出值是这种类型的默认值。

键值集合

字典的键,和值,可以单独作为一个集合使用。
使用属性访问他们。不过,这种集合类型是字典的嵌套类,既不是数组,也不是列表,或是其他的东西。
c#中的类数组数据集合_第1张图片
他们的内容不保证顺序,不过保证相同索引下,键集合和值集合中的元素是匹配的。

在对字典使用foreach或LINQ时,会生成键值对结构。
这个结构只有两个属性,键和值。并且他具有析构方法,可以析构成元组。
c#中的类数组数据集合_第2张图片

多维数组

多维数组,类似数组的数组。
但是多个长度和逗号都写在一个中括号内。

int[,,] arr = new int[6, 8, 10];

数组的数组,各数组的长度可能不同。也被称为交错数组。
多维数组各维度长度是相同的。一般来说在确定能装满的情况下才会使用。

多维数组不享受单维数组的操作。例如Array.Sort的排序方法,对多维数组会报错。
例如无法使用LINQ。

访问和修改

多维数组也使用索引访问,需要保证各个维度上的索引都没有越界。

arr[1, 2, 3] = 16;
int c = arr[2, 4, 8];

遍历

多维数组仍然可以foreach,但不是通过IEnumerable接口,而是通过IEnumerator接口。
所以多维数组没有LINQ方法。

多维数组使用for循环时,可以使用GetLength方法获得各个维度的长度。索引从0开始。

for (int i = 0; i < arr.GetLength(0); i++)
{
    for (int j = 0; j < arr.GetLength(1); j++)
    {
        for (int k = 0; k < arr.GetLength(2); k++)
        {
            Console.WriteLine(arr[i, j, k]);
        }
    }
}

你可能感兴趣的:(c#,开发语言)