Skip to main content

ArrayList

面试题

  1. ArrayList 和数组的区别?
  2. ArrayList 和 List<T>的区别?

📊 概念

ArrayList 是 C# 中的非泛型动态数组(位于 System.Collections命名空间),可存储任意类型的数据(所有元素均视为object` 类型)。

  • 动态大小:无需预定义长度,自动扩容。
  • 类型灵活:可混合存储不同类型(如整数、字符串、对象)。
  • 类型不安全:需显式类型转换,易引发运行时错误。
  • 性能损耗:值类型需装箱(存储)和拆箱(读取),增加开销。
  • 线程不安全:默认非线程安全,多线程需手动同步(如 ArrayList.Synchronized)。

与普通数组的区别

  • 固定数组:需预定义大小且类型统一(如int[] arr = new int[5]**)。
  • ArrayList:长度动态调整,支持混合类型存储,但需手动类型转换。

与 List<T> 的区别

现代开发中优先使用泛型集合 List<T>

  1. 类型安全:编译时检查类型,避免运行时错误。
  2. 无装箱拆箱:值类型直接存储,提升性能。
List<string> names = new List<string>();
names.Add("Alice"); // 仅允许字符串

⚙️ 底层结构与扩容机制

  • 底层实现:基于动态数组(内存连续分配)。
  • 扩容过程

img

  • 默认策略:容量不足时翻倍(如从 4 → 8 → 16),减少频繁内存分配。

⚠️ 关键特性与问题

优点

  • 动态大小:无需预定义长度,自动扩容。
  • 类型灵活:可混合存储不同类型(如整数、字符串、对象)。
ArrayList list = new ArrayList();
list.Add(42); // 整数
list.Add("Hello"); // 字符串
list.Add(new Person()); // 自定义对象

缺点

  • 类型不安全:需显式类型转换,易引发运行时错误。
string text = (string)list[0]; // 若索引0非字符串,抛出 InvalidCastException
  • 性能损耗:值类型需装箱(存储)和拆箱(读取),增加开销。
int num = 10;
list.Add(num); // 装箱:int → object
int value = (int)list[0]; // 拆箱:object → int
  • 线程不安全:默认非线程安全,多线程需手动同步(如 ArrayList.Synchronized)。

🛠️ 常用方法

方法作用示例
Add(object)末尾添加元素list.Add("Apple")
Insert(int, object)指定索引插入元素list.Insert(0, 100)
Remove(object)删除首个匹配项list.Remove("Apple")
RemoveAt(int)删除指定索引元素list.RemoveAt(0)
TrimToSize()释放多余内存(容量 = 元素数)list.TrimToSize()
ArrayList list = new ArrayList();
list.Add(1);
list.Add("World");
list.Insert(1, "Hello");
list.Remove(1); // 删除整数1

foreach (var item in list) {
Console.WriteLine(item); // 输出: Hello, World
}