数组不够用的时候,我发现了这些更好用的集合

前言

学完数组之后,我一直觉得有个地方不太舒服:数组的长度是固定的。

比如我声明了一个长度为5的数组,结果突然要多存一个数据,怎么办?没法办,只能重新建一个更大的数组,再把原来的数据复制过去...太麻烦了。

后来我学到了集合,这个问题终于解决了。

一、为什么我不想再用数组了?

数组确实简单直接,但它的限制也很明显:

  • 长度固定:一开始说好存5个,就只能存5个

  • 类型单一:声明成int数组,就只能存整数

  • 增删麻烦:想在中间插一个元素?自己写代码移位吧

直到我遇到了ArrayList,才发现原来可以这么方便。

二、ArrayList:我最先学会的集合

2.1 它是什么?

ArrayList可以理解成一个“会自动长大的数组”。你不用告诉它该多大,往里放东西就行,放不下了它会自己扩容。

用之前记得加上

using System.Collections;

2.2 我喜欢的几个操作

随便往里放东西

ArrayList list = new ArrayList();

// 啥类型都能放,这点太爽了
list.Add(1);           // 整数
list.Add("你好");      // 字符串
list.Add(true);        // 布尔值

插入和删除都很简单

// 在指定位置插入
list.Insert(1, "插在这里");

// 删除某个元素
list.Remove("你好");

// 删除某个位置的元素
list.RemoveAt(0);

// 一键清空
list.Clear();

查找也很方便

// 看看有没有这个元素
if (list.Contains(1))
{
    Console.WriteLine("存在");
}

// 看看现在有几个元素
int count = list.Count;

2.3 我踩过的一个坑

ArrayList虽然方便,但它取出来的数据默认是object类型。我存了个整数进去,取出来要转回整数才能用。

ArrayList list = new ArrayList();
list.Add(100);

// 必须转型,不然会报错
int num = (int)list[0];

老师说这叫拆箱,后面学了泛型就可以避免这个问题了。

三、Queue:我理解的“排队”

3.1 队列是什么?

Queue就是队列,跟排队买奶茶一样:先来的人先买到,后来的人排后面

计算机术语叫FIFO(先进先出)。

3.2 什么时候用队列?

老师举了几个例子,我觉得很好理解:

  • 打印机任务:先提交的文档先打印

  • 客服排队:先排队的用户先接入

  • 消息处理:先来的消息先处理

3.3 基本用法

存数据(入队)

Queue queue = new Queue();

queue.Enqueue("第一个人");
queue.Enqueue("第二个人");
queue.Enqueue("第三个人");
// 队列里:第一个人 → 第二个人 → 第三个人

取数据(出队)

// 取出并删除队首
string first = queue.Dequeue();  // 得到"第一个人"
// 现在队列只剩:第二个人 → 第三个人

// 只看不取(不删除)
string peek = queue.Peek();  // 得到"第二个人",队列不变

其他常用操作

// 看看有没有某个人
bool exists = queue.Contains("第二个人");

// 看看队伍多长
int count = queue.Count;

// 队伍解散
queue.Clear();

四、Stack:我理解的“叠盘子”

4.1 栈是什么?

Stack就是栈,像叠盘子一样:后放上去的盘子,会先被拿下来

计算机术语叫LIFO(后进先出)。

4.2 什么时候用栈?

老师举的例子我也记住了:

  • 浏览器后退:最后访问的页面最先退回

  • Ctrl+Z撤销:最后做的操作最先撤销

  • 叠盘子:后放的先拿

4.3 基本用法

存数据(入栈)

Stack stack = new Stack();

stack.Push("第一个");
stack.Push("第二个");
stack.Push("第三个");
// 栈顶是"第三个"

取数据(出栈)

// 取出并删除栈顶
string top = stack.Pop();  // 得到"第三个"
// 现在栈里:第一个 → 第二个(第二个在顶部)

// 只看不取
string peek = stack.Peek();  // 得到"第二个",栈不变

其他操作

// 看看有没有
bool exists = stack.Contains("第一个");

// 看看有几个
int count = stack.Count;

// 清空
stack.Clear();

五、我做的对比总结

学完这三个,我整理了一个表格方便记忆:

特性 ArrayList Queue Stack
外号 万能容器 排队 叠盘子
原则 按位置存取 先进先出 后进先出
取数据 通过索引 只能取队首 只能取栈顶
中间插入 可以 不行 不行

我的选择指南

  • 需要随便存随便取 → ArrayList

  • 模拟排队、任务处理 → Queue

  • 撤销操作、后退功能 → Stack

六、老师还提了一嘴泛型

老师说上面的ArrayList、Queue、Stack是非泛型集合,可以存任何类型,但也正因为这样,取出来需要转型。

后来微软推出了泛型版本,可以限定只能存一种类型:

非泛型 泛型版本 说明
ArrayList List<T> 只能存指定类型
Queue Queue<T> 只能存指定类型
Stack Stack<T> 只能存指定类型

// 泛型版本示例
List<int> numbers = new List<int>();  // 只能存int
numbers.Add(1);
// numbers.Add("abc");  // 这行会报错,存不了

泛型版本取数据不用转型,更安全,老师说以后会重点讲。

写在最后

学完集合之后,我写代码舒服多了。不用再纠结数组长度不够的问题,增删改查也有现成的方法。

一句话记住它们

  • ArrayList = 想存啥存啥的动态数组

  • Queue = 先来后到的排队

  • Stack = 后来居上的叠盘子

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐