# ArrayList
概念：
	`ArrayList` 是 C# 提供的一个==非泛型集合类==
	本质上可以理解成：==一个长度可变的 `object` 数组==

它可以：
1. 像数组一样按下标访问
2. 自动扩容
3. 增删查改元素
4. 存储任意类型的对象

命名空间：
```csharp
using System.Collections;
```

注意：
	是 `System.Collections`
	不是 `System.Collection`

----
# 通常用法
1. 学习 C# 早期非泛型集合
2. 理解 `object`、装箱和拆箱
3. 存储数量不固定的数据
4. 对数组进行更方便的增删操作

实际开发中：
	新代码更推荐使用 `List<T>`
	`ArrayList` 主要作为进阶阶段理解集合历史和装箱拆箱的材料

----
# 语法
创建：
```csharp
ArrayList list = new ArrayList();
```

添加：
```csharp
list.Add(数据);
```

访问：
```csharp
list[下标]
```

长度：
```csharp
list.Count
```

----
# 基础案例
```csharp
using System;
using System.Collections;

ArrayList list = new ArrayList();

list.Add("小明");
list.Add(18);
list.Add(true);

Console.WriteLine(list[0]);
Console.WriteLine(list[1]);
Console.WriteLine(list[2]);
Console.WriteLine(list.Count);
```

理解：
1. `ArrayList` 内部存的是 `object`
2. 所以字符串、整数、布尔值都可以放进去
3. `Count` 表示当前实际存了多少个元素

----
# 增删查改
增加：
```csharp
ArrayList list = new ArrayList();

list.Add("A");
list.Add("B");
list.Insert(1, "C");
```

结果：
```text
A C B
```

删除：
```csharp
list.Remove("A");   // 删除第一个匹配的元素
list.RemoveAt(0);   // 删除指定下标的元素
list.Clear();       // 清空所有元素
```

查找：
```csharp
bool hasB = list.Contains("B");
int index = list.IndexOf("B");
```

修改：
```csharp
list[0] = "新的值";
```

----
# 遍历
使用 `for`：
```csharp
ArrayList list = new ArrayList();
list.Add("A");
list.Add("B");
list.Add("C");

for (int i = 0; i < list.Count; i++)
{
	Console.WriteLine(list[i]);
}
```

使用 `foreach`：
```csharp
foreach (object item in list)
{
	Console.WriteLine(item);
}
```

因为 `ArrayList` 中的元素都是按 `object` 看待，所以 `foreach` 变量常写成 `object`。

----
# 取值时要类型转换
```csharp
ArrayList list = new ArrayList();
list.Add(100);

int num = (int)list[0];
Console.WriteLine(num);
```

原因：
	`list[0]` 的返回类型是 `object`
	如果要当成 `int` 使用，就需要拆箱 / 强制类型转换

错误示意：
```csharp
int num = list[0];
```

这样会报错，因为不能把 `object` 直接赋值给 `int`。

----
# 装箱和拆箱问题
```csharp
ArrayList list = new ArrayList();

int hp = 100;
list.Add(hp);        // int 放进 object，发生装箱

int value = (int)list[0]; // object 取回 int，发生拆箱
```

理解：
1. 值类型放进 `ArrayList` 时，会发生装箱
2. 从 `ArrayList` 取出值类型时，需要拆箱
3. 装箱和拆箱都有额外开销
4. 类型转错还会运行时报错

这个点可以和[[万物之父和装箱与拆箱|装箱与拆箱]]一起理解。

----
# Capacity 和 Count
`Count`：
	当前实际有多少个元素

`Capacity`：
	内部数组当前能容纳多少个元素

```csharp
ArrayList list = new ArrayList();

Console.WriteLine(list.Count);
Console.WriteLine(list.Capacity);

list.Add("A");
list.Add("B");

Console.WriteLine(list.Count);
Console.WriteLine(list.Capacity);
```

理解：
	`ArrayList` 内部会自动扩容
	`Count` 是实际数量
	`Capacity` 是容量，不一定等于数量

----
# 排序和反转
排序：
```csharp
ArrayList list = new ArrayList();
list.Add(3);
list.Add(1);
list.Add(2);

list.Sort();
```

反转：
```csharp
list.Reverse();
```

注意：
	如果里面混放了不能互相比较的类型，`Sort()` 可能会出错

例如：
```csharp
list.Add(10);
list.Add("A");
list.Sort(); // 可能出错
```

所以虽然 `ArrayList` 可以存任意类型，但最好不要随便混放。

----
# 和数组的区别
| 对比点  | 数组        | ArrayList      |
| ---- | --------- | -------------- |
| 长度   | 创建后固定     | 可以动态增删         |
| 类型   | 通常固定一种类型  | 内部按 `object` 存 |
| 访问   | 可以用下标     | 可以用下标          |
| 性能   | 类型明确，性能较好 | 可能有装箱拆箱        |
| 常用程度 | 基础常用      | 现在新项目较少用       |

----
# 常见错误
错误1：忘记引用命名空间
```csharp
ArrayList list = new ArrayList();
```

解决：
```csharp
using System.Collections;
```

----
错误2：取值时忘记强转
```csharp
ArrayList list = new ArrayList();
list.Add(10);

int num = list[0];
```

应该写：
```csharp
int num = (int)list[0];
```

----
错误3：混放类型后强转错误
```csharp
ArrayList list = new ArrayList();
list.Add("100");

int num = (int)list[0];
```

`list[0]` 实际是字符串，不是整数，会出错。

----
# 注意
1. `ArrayList` 在 `System.Collections` 命名空间中
2. `ArrayList` 是非泛型集合，内部按 `object` 存储
3. 它可以动态增删元素
4. 取出元素时通常需要强制类型转换
5. 值类型放入 `ArrayList` 会发生装箱
6. 不建议随意混放不同类型，容易产生转换错误
7. 新项目通常优先使用 `List<T>`，类型更安全

----
# 一句话记忆
==ArrayList 是会自动扩容的 object 数组，方便但不够类型安全。==

----
# 面试/复习时怎么说
可以这样答：

“ArrayList 是 `System.Collections` 命名空间下的非泛型集合，本质上可以理解为动态扩容的 `object` 数组。  
它可以存储任意类型，但取值时通常需要强制类型转换，值类型放进去还会发生装箱。  
所以它适合用来理解非泛型集合和装箱拆箱，新项目中一般更推荐使用泛型集合 `List<T>`。”

----
引用：
1. Microsoft Learn: [ArrayList Class](https://learn.microsoft.com/en-us/dotnet/api/system.collections.arraylist?view=net-9.0)
2. Microsoft Learn: [System.Collections Namespace](https://learn.microsoft.com/en-us/dotnet/api/system.collections?view=net-9.0)

#ArrayList
#集合
#进阶
