List<T> 类与 ArrayList 类比较类似。它实现了 IList<T> 泛型接口,长度可以动态增加。

可以使用 AddAddRange 方法将项添加到 List<T> 。

List<T> 类使用的相等比较器和排序比较器如下:

  • ContainsIndexOfLastIndexOf、和 Remove 用于对列表中的元素进行相等比较。默认的相等比较器 T 按如下方式确定:如果类型 T 实现 IEquatable<T> 泛型接口,则相等比较器是 Equals(T) 方法该接口; 否则,默认的相等比较器是 Object.Equals(Object)

  • BinarySearchSort 用于对列表元素进行排序。类型的默认比较器 T 按如下方式确定:如果类型 T 实现 IComparable<T> 泛型接口,则默认比较器是 CompareTo(T) 方法该接口; 否则为如果类型 T 实现非泛型 IComparable 接口,则默认比较器是 CompareTo(Object) 该接口的方法。 如果类型 T 实现两个接口,则没有默认比较器,并且必须显式提供一个比较器或比较委托。

List<T> 不保证进行排序。 您必须对 List<T> 执行的操作之前进行排序 (如 BinarySearch) 。

可以使用整数索引访问此集合中的元素。 在此集合中的索引是从零开始。

当元素个数非常多时,您可以在64位系统上,把配置信息中的 enabled 属性设置为 true ,来获取20亿的容量。

List<T> 接受值为 null 的引用类型,并允许重复。

性能注意事项


在决定是否使用 List<T> 或 ArrayList 类,这两个具有类似的功能,请记住, List<T> 类在大多数情况下更好地执行,并且是类型安全。 如果引用类型用于类型 T 的 List<T> 类,这两个类的行为是完全相同。 但是,如果值类型用于类型 T, ,您需要考虑实现和装箱问题。

如果值类型用于类型 T, ,编译器将生成的实现 List<T> 专门针对该值类型的类。 这意味着一个列表元素的 List<T> 对象没有进行装箱就可以使用该元素,并且会创建大约 500 个列表元素后不对列表元素装箱所节省的内存大于用来生成的类实现的内存。

请确保用于类型的值类型 T 实现 IEquatable<T> 泛型接口。 如果不是,方法如 Contains 必须调用 Object.Equals(Object) 框受影响的列表元素的方法。 如果值类型实现 IComparable 接口,并且您拥有源代码,则还应实现 IComparable<T> 泛型接口,以防止 BinarySearchSort 中装箱列表元素的方法。 如果您不拥有的源代码,将传递 IComparer<T> 对象传递给 BinarySearchSort 方法

若要使用强类型集合或使用特定类型的集合,则优先选择 List<T> 类,而不要选择 ArrayList 类,也不要自己写一个强类型的集合容器。是或自己编写强类型包装器集合。原因是一些功能 .NET 框架已经帮你实现,并且公共语言运行时可以共享 Microsoft 中间语言代码和元数据,而这点您的代码无法做到。

using System;
using System.Collections.Generic; // 简单的业务对象,会员Id用来区分不同的会员
// 会员名称可以修改
public class Part : IEquatable<Part>
{
public string PartName { get; set; } public int PartId { get; set; } public override string ToString()
{
return "ID: " + PartId + " Name: " + PartName;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
Part objAsPart = obj as Part;
if (objAsPart == null) return false;
else return Equals(objAsPart);
}
public override int GetHashCode()
{
return PartId;
}
public bool Equals(Part other)
{
if (other == null) return false;
return (this.PartId.Equals(other.PartId));
}
// 还需要重载 == 合 != 运算符
// TODO..
}
public class Example
{
public static void Main()
{
// 创建一个会员列表
List<Part> parts = new List<Part>(); // 向列表中添加会员
parts.Add(new Part() { PartName = "crank arm", PartId = });
parts.Add(new Part() { PartName = "chain ring", PartId = });
parts.Add(new Part() { PartName = "regular seat", PartId = });
parts.Add(new Part() { PartName = "banana seat", PartId = });
parts.Add(new Part() { PartName = "cassette", PartId = });
parts.Add(new Part() { PartName = "shift lever", PartId = }); // 输出会员列表中的会员,这里将调用在Part类中重写的ToString方法
Console.WriteLine();
foreach (Part aPart in parts)
{
Console.WriteLine(aPart);
} // 检查列表中是否存在id为1734的会员。这里调用Part类中重写的IEquatable.Equals方法
// 它用来比较会员的id
Console.WriteLine("\nContains(\"1734\"): {0}",
parts.Contains(new Part { PartId = , PartName = "" })); // 在第2个位置上添加一个会员
Console.WriteLine("\nInsert(2, \"1834\")");
parts.Insert(, new Part() { PartName = "brake lever", PartId = }); //Console.WriteLine();
foreach (Part aPart in parts)
{
Console.WriteLine(aPart);
} Console.WriteLine("\nParts[3]: {0}", parts[]);
Console.WriteLine("\nRemove(\"1534\")"); // 这里将移除id为1534、名称为cogs的会员
// 虽然会员名称不一样,但是Equals方法只比较会员的id
parts.Remove(new Part() { PartId = , PartName = "cogs" }); Console.WriteLine();
foreach (Part aPart in parts)
{
Console.WriteLine(aPart);
}
Console.WriteLine("\nRemoveAt(3)");
//这里将移除排在第4位的会员
parts.RemoveAt(); Console.WriteLine();
foreach (Part aPart in parts)
{
Console.WriteLine(aPart);
} /*
ID: 1234 Name: crank arm
ID: 1334 Name: chain ring
ID: 1434 Name: regular seat
ID: 1444 Name: banana seat
ID: 1534 Name: cassette
ID: 1634 Name: shift lever Contains("1734"): False Insert(2, "1834")
ID: 1234 Name: crank arm
ID: 1334 Name: chain ring
ID: 1834 Name: brake lever
ID: 1434 Name: regular seat
ID: 1444 Name: banana seat
ID: 1534 Name: cassette
ID: 1634 Name: shift lever Parts[3]: ID: 1434 Name: regular seat Remove("1534") ID: 1234 Name: crank arm
ID: 1334 Name: chain ring
ID: 1834 Name: brake lever
ID: 1434 Name: regular seat
ID: 1444 Name: banana seat
ID: 1634 Name: shift lever RemoveAt(3) ID: 1234 Name: crank arm
ID: 1334 Name: chain ring
ID: 1834 Name: brake lever
ID: 1444 Name: banana seat
ID: 1634 Name: shift lever
*/
}
}

常用属性和方法 

下面的示例演示List<T>类型常用的几个属性和方法:

using System;
using System.Collections.Generic; namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
//创建泛型List类实例
List<string> strList = new List<string>(); //向List类实例中添加数据
strList.Add("");
strList.Add("");
strList.Add("");
strList.Add(""); //使用匿名委托显示字符串List的值
Action<string> Show = delegate (string strToShow)
{
Console.WriteLine("当前元素值{0}", strToShow);
};
//在指定的位置插入元素
strList.Insert(, "");
//显示每个元素的值
strList.ForEach(Show); //未压缩前List的容量
Console.WriteLine("包含{0}个元素,可包含{1}个元素", strList.Count, strList.Capacity);
//压缩List
strList.TrimExcess();
//压缩后List的容量
Console.WriteLine("包含{0}个元素,可包含{1}个元素", strList.Count, strList.Capacity); //检查List中是否包含指定的元素
Console.WriteLine("是否包含数据\"15\":{0}", strList.Contains(""));
//使用索引值访问指定元素
Console.WriteLine("第2个元素:{0}", strList[]);
//从List中删除指定元素
bool result = strList.Remove(""); //创建List的匿名委托
Converter<string, int> converter = delegate (string strIn)
{
return int.Parse(strIn);
};
//使用匿名委托显示整型List的值
Action<int> print = delegate (int intToPrint)
{
Console.WriteLine("当前元素值:{0}", intToPrint);
};
//使用匿名委托将字符串List类实例转换为整型List类实例
List<int> iList = strList.ConvertAll<int>(converter);
//显示每个元素的值
iList.ForEach(print); Console.ReadLine(); /*
当前元素值10
当前元素值11
当前元素值15
当前元素值12
当前元素值13
包含5个元素,可包含8个元素
包含5个元素,可包含5个元素
是否包含数据"15":True
第3个元素:15
当前元素值10
当前元素值11
当前元素值15
当前元素值12
当前元素值13
*/
}
}
}

线程安全

可以安全地执行多个读取 List<T> 的操作,但如果在读取时修改该集合,可能会出现问题。

若要确保线程安全,读取过程中锁定集合,或写入操作。 若要启用访问集合以进行读取和写入的多个线程,则必须实现自己的同步。 具有内置同步的集合,请参阅中的类 System.Collections.Concurrent 命名空间。 本质上是线程 – 安全替代方法,请参阅 ImmutableList<T> 类。

参考资料:

1.《C# 编程兵书》第7章

2. https://msdn.microsoft.com/zh-cn/library/6sh2ey19(v=vs.110).aspx

3. https://msdn.microsoft.com/zh-cn/library/b0zbh7b6.aspx

List 的属性与方法整理的更多相关文章

  1. Vue2.x源码学习笔记-Vue实例的属性和方法整理

    还是先从浏览器直观的感受下实例属性和方法. 实例属性: 对应解释如下: vm._uid // 自增的id vm._isVue // 标示是vue对象,避免被observe vm._renderProx ...

  2. python 列表的属性和方法整理

    list属性和方法 补一个超实用的函数 envmerate(列表名, [start=0])  作用:  将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用 ...

  3. js DOM Element属性和方法整理

    节点操作,属性 1. childNodes.children 这两个属性获取到的子节点会根据浏览器的不同而不同的,所以一定要判断下nodeType是否为1. childNodes获取到的是NodeLi ...

  4. js element类型的属性和方法整理

    Element类型 除了Document类型,我们Web编程中最常用的类型就是Element类型啦.Element 类型用于表现XML或HTML元素,提供了对元素标签名,子节点,特性的访问 特征 no ...

  5. JavaScript:如何获得 Private、Privileged、Public 和 Static 成员(属性和方法)【翻译+整理】

    本文内容 背景 把我们的对象放在一起 添加一个私有(Private)的属性 添加一个特权(Privileged)的方法 添加一个公共(Public)的属性和方法 添加一个静态(Static)的属性 我 ...

  6. php面向对象基础知识整理之类中的属性和方法的使用

    <?php /** * class Index * 类包含什么 * 1.创建类 * 2.类的属性和类中方法 * 3.类中访问修饰符 * 4.类的封装.继承.多态 */ // 创建类,创建的类名是 ...

  7. js中Number对象与MATH方法整理总结

    W3C的文档: Number 对象属性 属性 描述 constructor 返回对创建此对象的 Number 函数的引用. MAX_VALUE 可表示的最大的数. MIN_VALUE 可表示的最小的数 ...

  8. js中Array数组的属性和方法

    这是我自己整理出来的一些关于Array数组的属性和方法,即查即用. 1.Array.length属性:数组的项数组,始终返回0或者更大的值. 2.instanceof操作符:value instanc ...

  9. JS获取对象“属性和方法”的方法

    平时在写的代码过程中,经常会遇到对对象Object的数据处理.而在对对象的数据处理中,操作最频繁的是“数据引用”.“值的修改”.“获取关键字(属性)”.平时最烦的也是“获取关键字”,经常忘记怎么去获取 ...

随机推荐

  1. Arctic Network POJ - 2349

    The Department of National Defence (DND) wishes to connect several northern outposts by a wireless n ...

  2. win10笔记本相机打开黑屏无法打开笔记本相机

    打开注册表编辑器(WINDOWS图标+R,或者右击左下角微软图标选择“运行(R)”),在出现的窗口输入regedit并回车(Enter)确定   进入HKEY_LOCAL_MACHINE \ SOFT ...

  3. Git回退---reset和revert

    今天学习了git回退的两个命令,现在总结一下: 1.git reset 如果想回退错误的提交C和D,只要把指针移到B上 git reset --hard a0fvf8 而这时候,远程仓库的指针还在D上 ...

  4. JSP的调试

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/debugging.html: 一.使用System.out.println() System.out.p ...

  5. SqlServer函数获取指定日期后的第某个工作日

    获取工作日 需要编写一个SqlServer函数,F_getWorkday,传入两个参数,第一个为时间date,第二个参数为第几个工作日num.调用F_getWorkday后返回date之后的第num个 ...

  6. Windows 10 S中的Device Guard详解(上篇)

    本文探讨Windows 10 S(下称Win10S)中的Device Guard(设备保护,下称DG).我将提取策略,并弄清楚在默认Win10S系统上可以和不可以运行什么.我将在下一篇文章中介绍在不安 ...

  7. 贪吃蛇 c++ ncurses

    近期学ncurses.用贪吃蛇训练下 思路:不构造链表.蛇头向前进方向打点,蛇尾逐点消失,形成移动. 须要记录蛇头方向,蛇尾方向.并用list仿造队列,增加拐点信息(空间比链表每一个结点开辟空间节省非 ...

  8. form 表单序列化 serialize

    在开发中有时需要在js中提交form表单数据,就需要将form表单进行序列化. jquery提供的serialize方法能够实现. $("#searchForm").seriali ...

  9. android学习笔记NO.5

    Intent 能够理解为信使 由Intent来协助完毕android各个组件之间的通讯. 感觉基础薄弱就又复习了一遍基础知识,整理了一遍! gen 保存自己主动生成的R资源目录 gen->com ...

  10. cnn,rnn,dnn

    CNN(卷积神经网络).RNN(循环神经网络).DNN(深度神经网络)的内部网络结构有什么区别? https://www.zhihu.com/question/34681168 CNN(卷积神经网络) ...