C# - List

List 是一个强类型对象的集合,可以通过索引访问,并具有排序、搜索和修改列表的方法。 它是 System.Collection.Generic 命名空间下的 ArrayList 的泛型版本。 有了这个之后我们基本不在用ArrayList了。

List 特征

  • List 等效于 ArrayList,它实现了 IList
  • 它位于 System.Collections.Generic 命名空间下。
  • List 可以包含指定类型的元素。 它提供编译时类型检查并且不执行装箱拆箱,因为它是通用的。
  • 可以使用 Add()、AddRange() 方法或集合初始值设定项语法添加元素。
  • 可以通过传递索引来访问元素,例如 我的列表[0]。 索引从零开始。
  • List 比 ArrayList 执行得更快,更不容易出错。

创建一个List Creating a List

List<T> 是一个泛型集合,因此您需要为其可以存储的数据类型指定一个类型参数。 以下示例展示如何创建列表和添加元素。

  static void Main(string[] args)
        {
            var numberList = new List<int>();
            numberList.Add(1); // 通用 add添加元素
            numberList.Add(3);
            numberList.Add(5);
            numberList.Add(7);

            var cities = new List<string>();
            cities.Add("北京");
            cities.Add("广州");
            cities.Add("上海");
            cities.Add("厦门");
            cities.Add(null); // null是允许的

            // 使用 集合初始值设定项 语法来添加元素 
            var bigCities = new List<string>()
                    {
                        "北京",
                        "广州",
                        "上海",
                        "厦门"
                    };
        }

在上面的例子中,我们使用 var numberList = new List<int>(); 来创建一个 int 类型的集合。 同样,我们也创建了cities 和 bigCities 都是字符串类型集合。 然后,您可以使用 Add() 方法或集合初始值设定项语法在列表中添加元素。

您还可以使用集合初始值设定项语法添加自定义类的元素。 下面在List中添加Student类的对象。

public class Student
{
    public int Id { get; set; }

    public string Name { get; set; }

}
class Program
{
    static void Main(string[] args)
    {
        var students = new List<Student>() 
        {
            new Student(){ Id = 1, Name="Ma"},
            new Student(){ Id = 2, Name="Le"},
            new Student(){ Id = 3, Name="Ma2"},
            new Student(){ Id = 4, Name="Hello"}
        };

    }
}

添加一组数据到list当中

使用 AddRange(IEnumerable<T> collection) 方法将数组或其他集合中的所有元素添加到 List。

        static void Main(string[] args)
        {
            var names = new List<string> { "baidu", "qq", "malema" };

            var popularNames = new List<string>();

            popularNames.AddRange(names);
        }

访问List元素

可以通过索引、for/foreach 循环和使用 LINQ 查询访问List。 List的索引从零开始。 与数组相同可以通过索引器来访问单个元素。 也可以使用 foreach 或 for 循环迭代 List 集合。

 var names = new List<string> { "baidu", "qq", "malema" };
            var popularNames = new List<string>();
            popularNames.AddRange(names);
            Console.WriteLine(names[0]); //baidu
            Console.WriteLine(names[1]); //qq
            foreach (var item in popularNames)
            {
                Console.WriteLine(item);
            }
            popularNames.ForEach(it => Console.WriteLine(it));

            for (int i = 0; i < names.Count; i++)
                Console.WriteLine(names[i]); //省略了大括号,不推荐

使用Linq语法来检索

static void Main(string[] args)
{
    var names = new List<string> { "baidu", "qq", "malema", "tencent", "alibaba" };

    var hasAList = names.Where(x => x.Contains("a"));
    //string.Join是可以把集合合拼起来。
    Console.WriteLine(string.Join(",", hasAList));// baidu,malema,alibaba

    var query = from it in hasAList where it.Contains('a') select it; //跟sql有类似的语法
    Console.WriteLine(string.Join(",", hasAList));// baidu,malema,alibaba
}

例子2

static void Main(string[] args)
{
    var students = new List<Student>()
    {
        new Student(){ Id = 1, Name="Ma"},
        new Student(){ Id = 2, Name="Le"},
        new Student(){ Id = 3, Name="Ma2"},
        new Student(){ Id = 4, Name="Hello"},
        new Student(){ Id = 5, Name="linq"}
    };

    var list = students.Where(it => it.Id > 3).Select(x => x.Name);
    Console.WriteLine(string.Join(",", list));  //Hello,linq
}

在任意位置插入一个新的元素 Insert elements in list

下面的代码就将student插入到了第一个student Ma之前了

static void Main(string[] args)
{
    var students = new List<Student>()
    {
        new Student(){ Id = 1, Name="Ma"},
        new Student(){ Id = 2, Name="Le"},
        new Student(){ Id = 3, Name="Ma2"},
        new Student(){ Id = 4, Name="Hello"},
        new Student(){ Id = 5, Name="linq"}
    };

    var student = new Student() { Name = "m-a-l-e-m-a" };
    students.Insert(0, student);
}

从List当中移除一个元素 Remove elements from List

我们可以使用RemoveAt(index) Remove(T item) 如下我们通过两种方式来移除元素

static void Main(string[] args)
{
    var students = new List<Student>()
    {
        new Student(){ Id = 1, Name="Ma"},
        new Student(){ Id = 2, Name="Le"},
        new Student(){ Id = 3, Name="Ma2"},
        new Student(){ Id = 4, Name="Hello"},
        new Student(){ Id = 5, Name="linq"}
    };

    students.RemoveAt(0); //移除第一个元素
    Console.WriteLine(string.Join(",", students.Select(x => x.Name)));//Le,Ma2,Hello,linq
    students.Remove(students[0]);// 再次移除第一个元素
    Console.WriteLine(string.Join(",", students.Select(x => x.Name)));//Ma2,Hello,linq 

    //先找出要移除的元素
    var linqStudent = students.FirstOrDefault(it => it.Name == "linq");
    students.Remove(linqStudent);
    Console.WriteLine(string.Join(",", students.Select(x => x.Name)));//Ma2,Hello
}

传统方法 移除所有符合条件的

        static void Main(string[] args)
        {
            var students = new List<Student>()
            {
                new Student(){ Id = 1, Name="Ma"},
                new Student(){ Id = 2, Name="Le"},
                new Student(){ Id = 3, Name="Ma2"},
                new Student(){ Id = 4, Name="Hello"},
                new Student(){ Id = 5, Name="linq"}
            };

            foreach (var item in students.ToList())
            {
                // 为什么要在students后面加上.ToList因为不加的话会报错
                // System.InvalidOperationException:“Collection was modified; enumeration operation may not execute.”
                if (item.Name == "linq")
                {
                    students.Remove(item);
                }
            }
        }

可以用 students.RemoveAll(it => it.Name == "linq"); 代替上面的移除代码

判断元素是否存在

简单类型

var numbers = new List<int>() { 10, 20, 30, 40 };
numbers.Contains(10); // returns true
numbers.Contains(11); // returns false
numbers.Contains(20); // returns true

复杂类型

 static void Main(string[] args)
        {
            var students = new List<Student>()
            {
                new Student(){ Id = 1, Name="Ma"},
                new Student(){ Id = 2, Name="Le"},
                new Student(){ Id = 3, Name="Ma2"},
                new Student(){ Id = 4, Name="Hello"},
                new Student(){ Id = 5, Name="linq"}
            };

            var has = students.Any(x => x.Name == "linq"); //true
        }

构造函数

List() 初始化 List 类的新实例,该实例为空并且具有默认初始容量。
List(IEnumerable) 初始化 List 类的新实例,该实例包含从指定集合复制的元素并且具有足够的容量来容纳所复制的元素。
List(Int32) 初始化 List 类的新实例,该实例为空并且具有指定的初始容量。

属性

Capacity 获取或设置该内部数据结构在不调整大小的情况下能够容纳的元素总数。
Count 获取 List 中包含的元素数。
Item[Int32] 获取或设置指定索引处的元素。

方法

Add(T) 将对象添加到 List 的结尾处。
AddRange(IEnumerable) 将指定集合的元素添加到 List 的末尾。
AsReadOnly() 返回当前集合的只读 ReadOnlyCollection 包装器。
BinarySearch(Int32, Int32, T, IComparer) 使用指定的比较器在已排序 List 的某个元素范围中搜索元素,并返回该元素从零开始的索引。
BinarySearch(T) 使用默认的比较器在整个已排序的 List 中搜索元素,并返回该元素从零开始的索引。
BinarySearch(T, IComparer) 使用指定的比较器在整个已排序的 List 中搜索元素,并返回该元素从零开始的索引。
Clear() 从 List 中移除所有元素。
Contains(T) 确定某元素是否在 List 中。
ConvertAll(Converter<T,TOutput>) 将当前 List 中的元素转换为另一种类型,并返回包含已转换元素的列表。
CopyTo(Int32, T[], Int32, Int32) 从目标数组的指定索引处开始,将元素的范围从 List 复制到兼容的一维数组。
CopyTo(T[]) 从目标数组的开头开始,将整个 List 复制到兼容的一维数组。
CopyTo(T[], Int32) 从目标数组的指定索引处开始,将整个 List 复制到兼容的一维数组。
Equals(Object) 确定指定对象是否等于当前对象。(继承自 Object) Exists(Predicate) 确定 List 是否包含与指定谓词定义的条件匹配的元素。
Find(Predicate) 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的第一个匹配元素。
FindAll(Predicate) 检索与指定谓词定义的条件匹配的所有元素。
FindIndex(Int32, Int32, Predicate) 搜索与指定谓词所定义的条件相匹配的一个元素,并返回 List 中从指定的索引开始、包含指定元素个数的元素范围内第一个匹配项的从零开始的索引。
FindIndex(Int32, Predicate) 搜索与指定谓词所定义的条件相匹配的元素,并返回 List 中从指定索引到最后一个元素的元素范围内第一个匹配项的从零开始的索引。
FindIndex(Predicate) 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中第一个匹配元素的从零开始的索引。
FindLast(Predicate) 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的最后一个匹配元素。
FindLastIndex(Int32, Int32, Predicate) 搜索与指定谓词所定义的条件相匹配的元素,并返回 List 中包含指定元素个数、到指定索引结束的元素范围内最后一个匹配项的从零开始的索引。
FindLastIndex(Int32, Predicate) 搜索与由指定谓词定义的条件相匹配的元素,并返回 List 中从第一个元素到指定索引的元素范围内最后一个匹配项的从零开始的索引。
FindLastIndex(Predicate) 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中最后一个匹配元素的从零开始的索引。
ForEach(Action) 对 List 的每个元素执行指定操作。
GetEnumerator() 返回循环访问 List 的枚举数。
GetHashCode() 作为默认哈希函数。(继承自 Object) GetRange(Int32, Int32) 在源 List 中创建元素范围的浅表复制。
GetType() 获取当前实例的 Type。(继承自 Object) IndexOf(T) 搜索指定的对象,并返回整个 List 中第一个匹配项的从零开始的索引。
IndexOf(T, Int32) 搜索指定对象并返回 List 中从指定索引到最后一个元素这部分元素中第一个匹配项的从零开始索引。
IndexOf(T, Int32, Int32) 搜索指定对象并返回 List 中从指定索引开始并包含指定元素数的这部分元素中第一个匹配项的从零开始索引。
Insert(Int32, T) 将元素插入 List 的指定索引处。
InsertRange(Int32, IEnumerable) 将集合中的元素插入 List 的指定索引处。
LastIndexOf(T) 搜索指定对象并返回整个 List 中最后一个匹配项的从零开始索引。
LastIndexOf(T, Int32) 搜索指定对象并返回 List 中从第一个元素到指定索引这部分元素中最后一个匹配项的从零开始的索引。
LastIndexOf(T, Int32, Int32) 搜索指定对象并返回 List 中到指定索引为止包含指定元素数的这部分元素中最后一个匹配项的从零开始索引。
MemberwiseClone() 创建当前 Object 的浅表副本。(继承自 Object) Remove(T) 从 List 中移除特定对象的第一个匹配项。
RemoveAll(Predicate) 移除与指定的谓词所定义的条件相匹配的所有元素。
RemoveAt(Int32) 移除 List 的指定索引处的元素。
RemoveRange(Int32, Int32) 从 List 中移除一系列元素。
Reverse() 将整个 List 中元素的顺序反转。
Reverse(Int32, Int32) 将指定范围中元素的顺序反转。
Sort() 使用默认比较器对整个 List 中的元素进行排序。
Sort(Comparison) 使用指定的 Comparison,对整个 List 中的元素进行排序。
Sort(IComparer) 使用指定的比较器对整个 List 中的元素进行排序。
Sort(Int32, Int32, IComparer) 使用指定的比较器对 List 中某个范围内的元素进行排序。
ToArray() 将 List 的元素复制到新数组中。
ToString() 返回表示当前对象的字符串。(继承自 Object) TrimExcess() 将容量设置为 List 中元素的实际数目(如果该数目小于某个阈值)。
TrueForAll(Predicate) 确定 List 中的每个元素是否都与指定谓词定义的条件匹配。

并发情况下对应的类型是 ConcurrentBag

上一篇:C# 集合
下一篇:C# SortedList
最近更新的
...