.NET数据结构:
关于ArrayList和List为什么实际上不同的更多讨论
数组
正如一个用户所说,数组是“老派”集合(是的,数组虽然不是的一部分,但被认为是一个集合System.Collections
)。但是,与其他集合(即您在标题中列出的集合)(这里为ArrayList和List(Of T))相比,关于数组的“旧派”是什么?让我们从数组的基础开始。
首先,Microsoft .NET中的数组是“使您可以将几个与逻辑相关的项目视为一个集合的机制”(请参阅链接的文章)。那是什么意思?数组按顺序存储各个成员(元素),并以起始地址依次存储在内存中。通过使用数组,我们可以轻松访问从该地址开始的顺序存储的元素。
除此之外,与对101个常见概念进行编程相反,Arrays确实可能非常复杂:
数组可以是一维,多维或交错的(锯齿状的数组值得一读)。数组本身不是动态的:初始化后,大小为n的数组保留足够的空间来容纳n个对象。数组中元素的数量不能增加或减少。Dim _array As Int32() = New Int32(100)
在内存块上保留足够的空间,以使数组包含100个Int32基本类型对象(在这种情况下,数组初始化为包含0)。该块的地址返回到_array
。
根据这篇文章,公共语言规范(CLS)要求所有数组都从零开始。.NET中的数组支持基于非零的数组。但是,这种情况不太常见。由于从零开始的数组的“普遍性”,Microsoft花了很多时间优化其性能。因此,基于零的零维(SZ)数组是“特殊”的-的确是数组的最佳实现(与多维等相对),因为SZ具有用于操纵它们的特定中间语言指令。
数组总是通过引用(作为内存地址)传递的-这是Array难题中要了解的重要部分。当他们进行边界检查(会引发错误)时,也可以在数组上禁用边界检查。
同样,数组的最大障碍是它们无法调整大小。他们具有“固定”的能力。向我们的历史介绍ArrayList和List(Of T):
ArrayList-非泛型列表
最好将ArrayList(以及List(Of T)
-尽管有一些关键的区别,在后面进行解释)-最好被认为是集合的下一个补充(广义上)。ArrayList继承自IList(“ ICollection”的后代)接口。ArrayList本身比List 更大,需要更多的开销。
IList
确实使实现能够将ArrayList视为固定大小的列表(如Arrays);但是,除了ArrayLists增加的其他功能之外,使用固定大小的ArrayList并没有真正的优势,因为在这种情况下ArrayLists(相对于Arrays)明显较慢。
根据我的阅读,ArrayLists不能锯齿:“不支持将多维数组用作元素...”。同样,在ArrayLists的棺材中还有另一个钉子。ArrayList也不是“类型化”的-意思是,在所有内容的下方,ArrayList只是一个动态对象数组:Object[]
。在实现ArrayList时,这需要大量装箱(隐式)和拆箱(显式),这又增加了它们的开销。
毫无根据的想法:我想我记得读过或听过我的一位教授的话说,ArrayList只是尝试从Arrays迁移到List-type Collections的混蛋概念子,即曾经对Arrays进行了很大的改进,它们已不再是最佳选择,因为已经对集合进行了进一步的开发
List(Of T):什么是ArrayList成为(并希望成为)
内存使用率的差异非常明显,以至于List(Of Int32)所消耗的内存比包含相同原始类型的ArrayList少56%(在上述绅士的链接演示中为8 MB与19 MB:再次,在此处链接)-尽管这是64位计算机造成的结果。这种差异确实说明了两件事:第一,装箱的Int32类型的“对象”(ArrayList)比纯Int32基本类型(List)大得多。第二(2),由于64位计算机的内部工作,差异是指数级的。
那么,有什么区别,List(Of T)是什么?MSDN定义List(Of T)
为“ ...索引可以访问的对象的强类型列表”。这里的重要性是“强类型”位:List(Of T)“识别”类型并将对象存储为它们的类型。因此,an Int32
存储为an Int32
而不是Object
类型。这消除了装箱和拆箱引起的问题。
MSDN指定这种区别仅在存储原始类型而不是引用类型时起作用。差异实际上也确实是大规模的:超过500个元素。更为有趣的是,MSDN文档中写道:“使用List(Of T)类的特定于类型的实现而不是使用ArrayList类对您来说是有利的。”
本质上,List(Of T)是ArrayList,但更好。它是ArrayList的“通用等效项”。像ArrayList一样,它不保证要排序后才能排序(如图)。List(Of T)还具有一些附加功能。