C#知识学习-006(​​列表(List))

1.​​列表是什么​​

先通过示例来学习,顺便带你回忆一下之前学习的内容(迭代语句以及字符串知识)

创建一个字符串列表,向该列表添加三个名称,并通过循环打印所有名称

在打印名称的时候,调用ToUpper()的方法,将它们替换为大写字母。

代码示例如下:

List<string> names = ["bo luo", "xiao bo luo", "xiao bo"];
foreach (var name in names)
{
    Console.WriteLine($"Hello {name.ToUpper()}!");
}

2.创建列表

2.1 new List<T>()

List<T> 的 ​T 是泛型类型参数​​,它让列表变得极其灵活,T可以是int,string,double,bool等等

我会举一些常见的例子:

// 创建字符串列表(初始为空)
List<string> names = new List<string>();

// 添加元素
names.Add("boLuo");
names.Add("xiao bo luo");
// 创建整数列表
List<int> numbers = new List<int>();
numbers.Add(10);
numbers.Add(20);

 2.2 用 {} 直接初始化

// 创建字符串列表并初始化元素
List<string> names = new List<string> { "xiao", "bo", "luo" };

// 简化写法
List<int> scores = new() { 90, 85, 78 }; 

2.3  使用集合表达式

// 最简洁写法(类似数组)
List<string> names = ["xiao", "bo", "luo"];
List<double> prices = [5.2, 3.8, 6.5];

3.基本操作

3.1 遍历列表

一般情况下foreach更常用,因为

  • 🛡️ ​​安全边界检查​​:自动处理边界,不会越界
  • 🔒 ​​遍历保护​​:遍历中修改集合会抛出 InvalidOperationException
  • 🔄 ​​顺序保证​​:严格按顺序遍历元素
List<string> names = new List<string>();

names.Add("boLuo");
names.Add("xiao bo luo");
names.Add("xiao bo");

//foreach循环
foreach (string name in names)
{
    Console.WriteLine($"{name}");
}

3.2  索引访问

我们可以使用索引(位置)来访问列表中的元素。在C#中,列表的索引从0开始,也就是说第一个元素的位置是0,第二个是1,以此类推。使用方括号[ 索引 ]来访问特定位置的元素。

注意:索引必须在0到列表元素个数减1的范围内,否则会抛出ArgumentOutOfRangeException异常。O(1)时间复杂度​​:无论列表大小,访问任意位置元素都同样快

List<string> names = ["xiao", "bo", "luo"];

Console.WriteLine($"{names[1]}");
Console.WriteLine($"{names[2]}");

3.3 增删元素

以下是诸多的例子以及结果,希望能让你更好的理解。

3.3.1添加单个元素

📍 元素添加的位置:​​永远被添加到列表的末尾​​(最后的位置)

List<int> numbers = [10, 20, 30];

// 添加单个元素
numbers.Add(40); //添加后[10, 20, 30, 40]

foreach (int number in numbers)
{
    Console.WriteLine($"num: {number}");
}

补充:添加操作的特性(简单了解即可)

特性说明示例
​自动扩容​列表会自动增大容量初始容量4 → 添加第5个元素时容量翻倍为8
​高效追加​O(1) 时间复杂度(平均情况)添加100万个元素也很快

你可以想象列表是一个​​可伸缩的容器​​:

  1. 初始状态:给你一个 ​​容量为4的盒子​​(可以放4个元素)
  2. 当盒子装满时:再添加第5个元素时,系统会​​自动换一个更大的盒子​​(容量翻倍为8)
  3. 继续添加:当装满8个后,再换16容量的盒子,以此类推

除了在末尾添加元素,还可以在指定位置添加

操作方法位置示例
​添加​Add()总是末尾numbers.Add(40); → 位置3
​插入​Insert()指定位置numbers.Insert(1, 50) → 在索引1插入元素50

💡 ​​最佳实践​​:当需要顺序收集数据且不关心位置时,优先使用 Add();当需要在特定位置插入元素时,使用 Insert()

3.3.2 批量添加元素

需要批量添加元素时,推荐使用AddRange(),当然所有新元素按顺序追加到列表末尾

List<int> numbers = [10, 20, 30];

// 添加多个元素
numbers.AddRange([50, 60]);

foreach (int number in numbers)
{
    Console.WriteLine($"num: {number}");
}

同样的,我们也可以在指定位置批量添加元素

List<int> numbers = [10, 20, 30];

// 添加多个元素
numbers.InsertRange(1, [50, 60]);//插入后[10, 50, 60, 20, 30]

3.3.3 删除指定元素

按值删除使用Remove(item),它会删除列表中​​第一个匹配​的元素,并且只删除第一个匹配项

List<int> numbers = [10, 20, 30];

// 删除指定元素
numbers.Remove(20);

foreach (int number in numbers)
{
    Console.WriteLine($"num: {number}");
}

按索引删除使用RemoveAt(index),它会删除​​指定索引位置​​的元素

  • 必须确保索引有效​​(0 ≤ index < Count)
List<int> numbers = [10, 20, 30];

// 删除指定位置元素
numbers.RemoveAt(0);//删除后变成[20, 30]

批量删除使用RemoveAll(match),它会删除​​所有满足条件​​的元素(先了解它的用法即可)

List<int> scores = [55, 89, 20, 72, 45];

// 删除所有不及格的分数
scores.RemoveAll(s => s < 60);//列表变为: [89, 72]

性能考虑

操作最佳场景时间复杂度
Remove()删除单个已知值O(n)
RemoveAt()删除已知位置元素O(n)
RemoveAll()批量删除满足条件的元素O(n)

3.3.4 清空列表

使用 Clear() 方法,时间复杂度 O(1),不会清除已分配的内存空间

List<int> numbers = [10, 20, 30];

// 清空列表
numbers.Clear();

3.4 获取数量

List<int> numbers = [10, 20, 30];
Console.WriteLine($"{numbers.Count}");//值为3

4. 进阶操作

如果上面的例子你都看懂了,现在试试更难的例子吧

4.1 搜索(IndexOf)

List<int> nums = [85, 92, 78, 95];
int index = nums.IndexOf(78);
// 查找78元素位置
Console.WriteLine($"78 pos is: {index}");

那如果我们查找一个并不存在的数字会得到什么?

会得到返回值:-1(统一使用 -1 表示未找到),带你验证一下

List<int> nums = [85, 92, 78, 95];
int index = nums.IndexOf(11);
// 查找11元素位置
Console.WriteLine($"11 pos is: {index}");

    关于Contains 方法,其用于快速检查元素是否存在于集合中

    • ​找到元素​​ → 返回 true
    • ​未找到元素​​ → 返回 false
    List<int> nums = [85, 92, 78, 95];
    bool exists = nums.Contains(95);
    // 判断95是否存在
    Console.WriteLine($"95 is: {exists}");//结果:True
    
    bool exist = nums.Contains(11);
    // 判断11是否存在
    Console.WriteLine($"11 is: {exist}");//结果:False

    4.2  排序(Sort)

    注意:默认是升序(从小到大)

    // 数值排序
    List<int> numbers = [85, 92, 78, 95];
    numbers.Sort();
    
    foreach (int number in numbers)
    {
        Console.WriteLine($"num: {number}");
    }

    // 数值降序
    List<int> numbers = [85, 92, 78, 95];
    numbers.Sort();//升序
    numbers.Reverse();//反转
    //结果为[95, 92, 85, 78]

    补充:

    关于字符串的排序,是按照拼音升序(排序依据:​​首字母 → 后续字母

    拼音升序​​指的是按照汉字的拼音字母顺序(类似英文字母 A-Z)进行排序

    List<string> names = ["xiao", "bo", "luo"];
    names.Sort();
    
    foreach (string name in names)
    {
        Console.WriteLine($"name: {name}");
    }

    本篇列举了大量的代码示例,希望你没有看晕噢,学到了这里,咱俩真棒,记得按时吃饭

    【本篇结束,新的知识会不定时补充】

    感谢你的阅读!如果内容有帮助,欢迎 ​​点赞❤️ + 收藏⭐ + 关注​​ 支持! 😊

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值