【发布时间】:2010-09-29 14:15:54
【问题描述】:
我经常使用ArrayList 而不是“普通”array[]。
当我使用 ArrayList 时,我觉得自己在作弊(或懒惰),什么时候可以在数组上使用 ArrayList?
【问题讨论】:
-
这不是作弊,而是让您的生活更轻松。您应该尽可能让您的生活更轻松。
我经常使用ArrayList 而不是“普通”array[]。
当我使用 ArrayList 时,我觉得自己在作弊(或懒惰),什么时候可以在数组上使用 ArrayList?
【问题讨论】:
是这样的。
using System;
using System.Collections;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
//ArrayList
/*
An ArrayList doesn't use a LinkedList as the internal data structure! .we can store any type of objects
*/
ArrayList list = new ArrayList();
list.Add("1"); // not strongly type,you can enter any object types (int,string decimals, etc..)
list.Add(1);
list.Add(1.25);
//Array
/*
must declare length.
*/
string[] array = new string[3]; // you must declare object types
array[0] = "1";
//array[1] = 1; this get error becoz array is storngly typed. // this print empty value when you run it
array[2] = "stongly typed";
Console.WriteLine("------- ARRAYLIST ITEMS ---------");
foreach (var i in list) {
Console.WriteLine(i);
}
Console.WriteLine("--------- ARRAY ITEMS -----------");
foreach (var i in array)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
}
}
【讨论】:
如果您需要原始类型数组,请使用 Array 以获得更好的性能,因为它可以避免自动装箱和拆箱。但前提是您提前知道想要的尺寸。
【讨论】:
【讨论】:
数组是强类型的,可以很好地用作参数。如果你知道你的集合的长度并且它是固定的,你应该使用一个数组。
ArrayList 不是强类型的,每次插入或重试都需要强制转换才能恢复到原始类型。如果您需要一种方法来获取特定类型的列表,那么 ArrayLists 就不够用了,因为您可以传入包含任何类型的 ArrayList。 ArrayLists 内部使用动态扩展数组,因此内部数组的大小在达到其容量时也有一个命中。
您真正想要使用的是像List<T> 这样的通用列表。这具有 Array 和 ArrayLists 的所有优点。它是强类型的,它支持可变长度的项目。
【讨论】:
我是从 Java 的角度回答这个问题,但这是同一个基本问题。你不应该因为使用更高的抽象而感到内疚。毕竟,您使用的是Strings 而不是char[],甚至是byte[]?我什至建议更进一步,尽可能使用List 接口。降级的唯一原因是性能原因。
使用更高的集合抽象有很多优点。您可以添加装饰器以使 List 成为只读、固定大小、检查进入或离开集合的项目或使用视图(请参阅 C# 中的 GetRange 和 Java 中的 subList。)
顺便说一句,ArrayList 应该始终基于原始数组,否则名称是错误的。这些操作通常按照您在使用原始数组时所期望的方式实现。如果使用链表,它通常被命名为——LinkedList。这也是使用接口的一个优势:您可以稍后改变对使用的实现的看法。
有一些事情使集合的使用变得笨拙。需要注意的是,集合通常基于对象,并且这些语言在原始类型和对象类型之间存在相当大的差距。有限的泛型也没有多大帮助。尽管如此,除非有充分的理由,否则我还是推荐集合而不是数组。
对于原始值,您还可以考虑使用原始集合库,例如GNU Trove。不过,不知道 C# 是否有类似的东西。
【讨论】:
数组的大小是静态的,所以如果您在设计时知道大小,请使用数组。它应该工作得更快,但我自己没有测试过。如果您需要经常更改对象的数量(从集合中添加或删除对象),请使用 ArrayList 或更好的 .NET 2 中的通用 List。它也更易于使用,因此如果性能不重要,您始终可以使用 List。
【讨论】:
除了 Bob 和 Frederick 的回应,我想指出,虽然数组具有协方差,但泛型列表没有。例如,MyChildClass[] 类型的数组可以很容易地转换为MyParentClass[],而List<MyChildClass> 不能转换为List<MyParentClass>,至少不能直接转换。
如果您需要协方差,可以使用数组、使用 LINQ 的 Cast() 方法或其他方法来单独转换每个项目或等待 C# 4。
【讨论】:
这里的另一个想法是突变;一个数组 (T[]) 是完全可变的,不能被保护。 List<T> 没有提供任何有用的扩展点,但像 Collection<T>(或许多其他 IList<T> 实现)之类的东西允许您添加代码,例如,在添加项目之前检查它们;同样,您可以拥有只读的IList<T> 实现,这对于需要不可变性的线程安全很有用。
我倾向于在内部方法逻辑(可能作为局部变量)中使用数组,作为params 参数,或者在一些我知道项目长度并且我知道代码的高度优化的情况下选择不改变它(作为私有字段)。除此之外,List<T> 等往往更常见,因为它们在添加/删除项目时的开销要少得多。
【讨论】:
首先,如果您只打算处理特定类型,则不应使用 ArrayList。例如,如果您只期望一个字节数组,那么您应该只接受一个字节数组。
只有在我认为您可能会想到使用 ArrayList 来代替 List 的时候。
【讨论】:
更好的是,无论您在何处使用 ArrayList,都请改用 List<T> 泛型集合。它的类型比前者强。
【讨论】:
除非这部分代码对性能非常关键,否则使用 ArrayList 是完全可以的。
【讨论】: