我们不能在 C# 中没有 add() 方法将数据添加到 ArrayList 中吗?
本文关键字:数据 方法 添加 中吗 ArrayList 不能 add 我们 | 更新日期: 2023-09-27 17:56:26
int[] x = new int[5];
x[0] = 1;
x[1] = 2;
x[2] = 3;
x[3] = 4;
x[4] = 5;
System.Collections.ArrayList y = new System.Collections.ArrayList(5);
y.Add(1);
y[2] = 2;
上面给出了运行时异常"Index was out of range. Must be non-negative and less than the size of the collection."
为什么会这样?我们不能使用与 int[] 数组相同的索引将数据添加到 ArrayList 中吗?请为我提供一些指示,以了解此实现背后的原因。
您的ArrayList
中只有一个条目,因此索引2
超出范围。 ArrayList#Add
添加到列表中。列表的初始容量为 5
,因为您调用了 ArrayList(Int32)
构造函数,但只向其添加了一个实际条目(该条目位于索引 0
处)。
您似乎唯一误解的是ArrayList
构造函数的作用。 new ArrayList(5)
不会创建具有五个元素的ArrayList
,而 new int[5]
会创建一个包含五个元素的数组(所有元素的值均为零)。新创建的ArrayList
始终为空,因此任何使用 []
设置任何元素的值的尝试都将失败,因为没有元素。如果您通过说 new int[0]
创建了数组,这与常规数组的行为相同 - 任何索引到它的尝试都会崩溃。获取五元素ArrayList
的唯一方法是使用将(五元素)集合作为参数的构造函数(如@Stilgar和@Kelon所示),或者通过调用例如 Add(0)
五次。完成此操作后,您可以访问 x[0]
, x[1]
, ..., x[4]
.
那么new ArrayList(n)
该怎么办呢?它创建了一个大小为零的ArrayList
,但是用于存储值的内部数组被赋予大小 n,以便我们可以在内部数组必须替换为更大的数组之前添加 n 个元素(这需要一点时间,这就是为什么在高性能方案中,如果您知道列表最终会变得多大,则可能需要使用此构造函数)。
new ArrayList(5)
只为 5 个条目分配内存。就这样。您仍然需要添加或插入到列表中 - 它与数组不同。
也许你需要使用集合而不是像List<int>();
这样的数组
至于为什么看到这个
http://msdn.microsoft.com/en-US/library/K2604H5S(v=vs.80).aspx
类库设计器可能需要 就何时做出艰难的决定 使用数组以及何时返回 收集。虽然这些类型有 类似的使用模式,他们有 不同的性能特征。 通常,您应该使用 添加、删除或其他时收集 操作 支持集合。
有关使用 集合,请参阅集合和数据 结构。
数组使用默认值初始化内存。列表具有不同的语义。他们应该动态管理自己的大小。您提供的容量 (5) 纯粹是基于特定列表实现的优化。并非每个 IList 实现都具有相同的内部表示形式。如果实现是链接列表怎么办?您需要考虑数据结构列表的概念,而不是特定实现。
如果要分配值,有很多方法可以初始化列表。可以将数组传递给构造函数或使用 C# 3.0 中的集合初始值设定项。并且请使用列表而不是数组列表。
//Collection initializer
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
//passing array as an argument to the constructor
int[] ints = new[] { 1, 2, 3, 4, 5 };
List<int> list2 = new List<int>(ints);
尝试
new ArrayList(new int[5]);
这将使用 5 个给定的默认条目初始化 ArrayList。
但
y.Add(1); // would add a 6t entry
您可以在创建ArrayList
时指定容量,但这只是为了让对象可以在内部分配空间,列表的初始大小仍然为零。
ArrayList
和数组之间的区别在于列表的大小是动态的。您可以添加和删除项目,这在数组中是不可能的。动态大小集合从大小零开始,而不是用零值填充它是有意义的。
注意:ArrayList
类实际上已经过时了;您应该改用泛型List<T>
类,它的性能更好且更易于使用,特别是对于像int
这样的值类型。