C# .NET集合类

C# .NET集合类,c#,.net,collections,C#,.net,Collections,一组相关数据,如零件列表等,可以使用数组(零件数组)或集合进行处理。我知道当使用数组时,插入、删除和其他一些操作与集合相比会对性能产生影响。这是否意味着集合不在内部使用数组?如果是,集合(如列表、集合等)使用的数据结构是什么 如何在内部处理集合?实现简单集合有两种基本方法: 连续数组 链表 连续数组对于您提到的操作有性能缺点,因为集合的内存空间是预先分配的,或者是根据集合的内容分配的。因此,删除或插入需要移动多个数组元素,以保持整个集合连续且顺序正确 链表会删除这些问题,因为集合中的项不需要

一组相关数据,如零件列表等,可以使用数组(零件数组)或集合进行处理。我知道当使用数组时,插入、删除和其他一些操作与集合相比会对性能产生影响。这是否意味着集合不在内部使用数组?如果是,集合(如列表、集合等)使用的数据结构是什么


如何在内部处理集合?

实现简单集合有两种基本方法:

  • 连续数组
  • 链表
连续数组对于您提到的操作有性能缺点,因为集合的内存空间是预先分配的,或者是根据集合的内容分配的。因此,删除或插入需要移动多个数组元素,以保持整个集合连续且顺序正确

链表会删除这些问题,因为集合中的项不需要连续存储在内存中。相反,每个元素都包含对一个或多个其他元素的引用。因此,当进行插入时,将在内存中的任何位置创建相关项,并且只需要修改集合中已有的一个或两个元素上的引用

例如:

LinkedList<object> c = new LinkedList<object>(); // a linked list
object[] a = new object[] { }; // a contiguous array
LinkedList c=new LinkedList();//链表
对象[]a=新对象[]{};//连续数组

这当然是简化的。
LinkedList
的内部结构无疑比简单的单链表或双链表更复杂,但这是基本结构

实现简单集合有两种基本方法:

  • 连续数组
  • 链表
连续数组对于您提到的操作有性能缺点,因为集合的内存空间是预先分配的,或者是根据集合的内容分配的。因此,删除或插入需要移动多个数组元素,以保持整个集合连续且顺序正确

链表会删除这些问题,因为集合中的项不需要连续存储在内存中。相反,每个元素都包含对一个或多个其他元素的引用。因此,当进行插入时,将在内存中的任何位置创建相关项,并且只需要修改集合中已有的一个或两个元素上的引用

例如:

LinkedList<object> c = new LinkedList<object>(); // a linked list
object[] a = new object[] { }; // a contiguous array
LinkedList c=new LinkedList();//链表
对象[]a=新对象[]{};//连续数组
这当然是简化的。
LinkedList
的内部结构无疑比简单的单链表或双链表更复杂,但这是基本结构

列表
使用内部数组。删除/插入列表开头附近的项目比在列表末尾附近删除/插入项目的成本更高,因为内部数组的全部内容需要向一个方向移动。此外,当内部列表已满时,一旦尝试添加项,将构造一个新的更大数组,复制内容,并丢弃旧数组

当与无参数构造函数一起使用时,
集合
类在内部使用
列表
。因此,在性能方面,它们将是相同的,但包装造成的开销除外。(本质上是多了一个间接层次,这在大多数场景中可以忽略不计。)

LinkedList
顾名思义是一个链接列表。这将牺牲插入/删除速度的迭代速度。因为迭代意味着无限次地遍历指针到指针到指针,所以这将需要更多的工作。除了指针遍历之外,两个节点可能不会分配到彼此相邻的任何位置,从而降低CPU RAM缓存的效率

但是,插入或删除节点所需的时间是恒定的,因为无论列表的状态如何,它都需要相同数量的操作。(这不考虑实际定位要删除的项或遍历列表以找到插入点所必须完成的任何工作!)

如果您对集合的主要关注是在测试集合中是否有什么东西,则可以考虑使用<代码>哈什集。将项目添加到集合中的速度相对较快,介于插入列表和链接列表之间。移除物品的速度也会相对较快。但真正的好处在于查找时间——测试

HashSet
是否包含项不需要迭代整个列表。平均而言,它的执行速度比任何列表或链表结构都快

但是,
HashSet
不能包含等效项。如果您的部分需求是两个被认为相等的项(通过
对象.Equals(Object)
重载,或者通过实现
IEquatable
)在集合中独立共存,那么您就不能使用
哈希集。另外,
HashSet
不能保证插入顺序,因此如果维护某种顺序很重要,您也不能使用
HashSet

List
使用内部数组。删除/插入列表开头附近的项目比在列表末尾附近删除/插入项目的成本更高,因为内部数组的全部内容需要向一个方向移动。此外,当内部列表已满时,一旦尝试添加项,将构造一个新的更大数组,复制内容,并丢弃旧数组

当与无参数构造函数一起使用时,
集合
类在内部使用
列表
。因此,在性能方面,它们将是相同的,但包装造成的开销除外。(本质上是一个更高的间接层次