ArrayList

ArrayList的本质是一个扩容object数组增删改查

1. ArrayList的声明

ArrayList array = new ArrayList();

2. ArrayList的增加

 ArrayList arrlist = new ArrayList();
 // Add 可以添加任意类型的
 arrlist.Add(1); // 添加int类型的
 arrlist.Add("unity"); // 添加string类型的
 arrlist.Add(false); // 添加bool类型的

 // AddRange 批量添加
 ArrayList sublist = new ArrayList();
 sublist.Add("sub");
 arrlist.AddRange(sublist);

 // Insert 在第几个位置插入
 arrlist.Insert(0, "shader");

3. ArrayList的删除

  • array.Remove(0); 删除值

  • array.RemoveAt(0); 删除第0个位置的元素

  • array.Clear(); 清空

4. ArrayList的修改

  • array[i] = value

5. ArrayList查找

  • array[i]

6. 装箱拆箱

添加元素时,将添加的元素转化为引用类型,叫装箱

取出元素时,将引用类型转化为值类型对象,叫拆箱

Stack

stack本质就是object数组,添加了先进后出的规则

1. Stack的声明

Stack stack = new Stack();

2. Stack的常用方法

  1. Push(T item):压栈

  2. Pop():出栈,栈顶移除并返回最上面的元素。如果栈为空,则会抛出 InvalidOperationException

  3. Peek():返回位于栈顶的元素但不将其移除。如果栈为空,则会抛出 InvalidOperationException

  4. Contains(T item):确定某个元素是否在栈中。返回 true 如果找到该元素,否则返回 false

  5. Clear():移除栈中的所有元素

  6. ToArray():将栈的元素复制到一个新的数组中,按照 LIFO 顺序排列(即栈顶元素是数组的第一个元素)

Queue

Queue本质是object数组

Queue<T> 是一个先进先出 (FIFO, First In First Out) 的集合类型,它位于 System.Collections.Generic 命名空间。

1. Queue的声明

Queue queue = new Queue();

2. Queue常用方法

  1. Enqueue(T item):入队,将一个元素添加到队列的末尾

  2. Dequeue():出队,从队列的开头移除并返回最前面的元素。如果队列为空,则会抛出 InvalidOperationException

  3. Peek():返回队列开头的元素但不将其移除。如果队列为空,则会抛出 InvalidOperationException

  4. Clear():移除队列中的所有元素

  5. Contains(T item):确定某个元素是否在队列中。返回 true 如果找到该元素,否则返回 false

HashTable

Hashtable 是 C# 中的一个非泛型集合类,位于 System.Collections 命名空间。

它是一个键值对的集合,其中每个键都是唯一的,并且可以通过键快速访问对应的值。

Hashtable 使用哈希算法来存储和检索数据,这使得查找、添加和删除操作通常都非常高效(平均时间复杂度为 O(1))。

然而,Hashtable 不是线程安全的,如果需要在多线程环境中使用,必须实现额外的同步机制。

1. HashTable的声明

HashTable hashTable = new HashTable();

2. HashTable的常用方法

  1. Add(object key, object value):向 Hashtable 添加带有指定键和值的元素。如果键已经存在,则抛出 ArgumentException。

  2. Remove(object key):移除具有指定键的元素。如果键不存在,则什么也不做。

  3. ContainsKey(object key):检查 Hashtable 是否包含指定的键。返回 true 如果找到该键,否则返回 false

  4. ContainsValue(object value):检查 Hashtable 是否包含指定的值。返回 true 如果找到该值,否则返回 false

  5. Clear():Hashtable 中移除所有元素

3. HashTable的遍历

 foreach (DictionaryEntry item in hashtable)
 {
     Console.WriteLine("键:" + item.Key + " 值:" + item.Value);
 }

Set

HashSet

SortedSet

  1. 自动排序:元素按升序排列(默认)或自定义顺序。

  2. 唯一性:不允许重复元素。

  3. 高性能:基于红黑树实现,插入、删除和查找的时间复杂度为 O(log n)

自动排序

// 需要引入命名空间
using System.Collections.Generic;

SortedSet<int> numbers = new SortedSet<int> { 5, 2, 8, 1, 3 };
// 输出顺序:1, 2, 3, 5, 8

自定义排序规则

// 使用自定义比较器(例如降序)
SortedSet<int> descendingSet = new SortedSet<int>(
    Comparer<int>.Create((x, y) => y.CompareTo(x))
);
descendingSet.Add(5);
descendingSet.Add(2);
// 输出顺序:8, 5, 3, 2, 1

List

List<T> 是 C# 中非常常用的一个泛型集合类,位于 System.Collections.Generic 命名空间中。它提供了动态数组的功能,允许你存储、检索和操作一组相同类型的对象。以下是 List<T> 的一些常用方法及其简要说明:

1. 构造函数

  • new List<T>():创建一个空的 List<T>

2. 添加元素

  • Add(T item):在列表的末尾添加一个元素。

  • AddRange(IEnumerable<T> collection):将集合中的所有元素添加到列表的末尾。

  • Insert(int index, T item):在指定索引位置插入一个元素。

3. 移除元素

  • Remove(T item):从列表中移除第一个匹配的元素。

  • RemoveAt(int index):移除指定索引处的元素。

  • Clear():移除列表中的所有元素。

4. 查找元素

  • Contains(T item):检查列表是否包含指定元素。

  • IndexOf(T item):返回第一个匹配元素的索引;如果未找到则返回 -1。

  • LastIndexOf(T item):返回最后一个匹配元素的索引;如果未找到则返回 -1。

5. 遍历和枚举

  • ForEach(Action<T> action):对列表中的每个元素执行指定的操作。

6. 转换

  • ToArray():将列表转换为数组。

7. List排序

7.1 List自带的排序方式

List<int> list = new List<int>();
list.Add(1);
list.Add(4);
list.Add(2);
list.Add(3);
list.Sort();
for(int i = 0; i < list.Count; i++)
{
    print(list[i]);
}

7.2 List自定义类的排序

类必须要实现IComparable接口,自定义排序规则

CompareTo方法的排序规则

  • 返回1,排在后面

  • 返回-1, 排在前面

  • 返回0, 不排序

public class Test : MonoBehaviour
{
    public void Test2()
    {
        List<Item > list = new List<Item>();
        list.Add(new Item(5, "血瓶"));
        list.Add(new Item(2, "蓝瓶"));
        list.Add(new Item(3, "斧头"));
        list.Add(new Item(4, "锄头"));
        list.Sort();
    }
}
public class Item:IComparable<Item>
{
    int id;
    string name;
    public Item(int id, string name)
    {
        this.id = id;
        this.name = name;
    }

    public int CompareTo(Item other)
    {
        return id > other.id ? 1 : -1;
    }
}

7.3 List通过委托函数进行排序

public class Test : MonoBehaviour
{
    public void Test2()
    {
        List<Item > list = new List<Item>();
        list.Add(new Item(5, "血瓶"));
        list.Add(new Item(2, "蓝瓶"));
        list.Add(new Item(3, "斧头"));
        list.Add(new Item(4, "锄头"));
        list.Sort((a,b) =>
        {
            return a.id > b.id ? -1 : 1;
        });
    }
}
public class Item
{
    public int id;
    public string name;
    public Item(int id, string name)
    {
        this.id = id;
        this.name = name;
    }
}

8. 容量和大小

  • Count:获取列表中实际包含的元素数量。

  • Capacity:获取或设置列表的容量(即内部数组的大小)。调整容量可以优化性能,特别是在大量添加元素时。

性能提示

  • 容量管理:如果你知道列表最终会包含多少个元素,可以在创建时设置 Capacity,以避免多次重新分配内存。

  • 批量操作:尽量使用 AddRangeRemoveAll 等批量操作方法,而不是在一个循环中逐个添加或移除元素,这样可以提高性能。

  • 避免频繁的插入和删除:List<T>在中间位置插入或删除元素时效率较低,因为这需要移动后续的元素。如果需要频繁的插入和删除操作,考虑使用 LinkedList<T>

Dictionary

Dictionary可以理解为拥有泛型的HashTable。它存储键/值对,并允许您以O(1)的时间复杂度通过键快速查找值。

其中每个键都必须是唯一的,而值可以重复。Dictionary 类位于 System.Collections.Generic 命名空间中。

1. Dictionary的声明

Dictionary<int, string> dic = new Dictionary<int, string>();

2. Dictionary的添加

注意:不是存在两个相同的键

// Add 添加
dic.Add(1, "shuwukong");

// AddRange 批量添加
Dictionary<int, string> subDic = new Dictionary<int, string>();
subDic.Add(2, "gun");
dic.AddRange(subDic);

3. Dictionary的删除

// Remove 通过键去删除
dic.Remove(0);

// Clear 清空字典
dic.Clear();

4. Dictionary的查找

注意:通过键查找,如果找不到直接报错

string value = dic[123];

if (dic.ContainsKey(123))
{
    Debug.Log("存在键为123的键值对")
}
if (dic.ContainsValue("heihei"))
{
    Debug.Log("存在值为heihei的键值对")
}

5. Dictionary的修改

dic[123] = "abc";

6. Dictionary的遍历

// 1. 遍历键
foreach (var item in dic.Keys)
{
    Debug.Log(item);
    Debug.Log(dic[item]);
}

// 2. 遍历值
foreach (var item in dic.Values)
{
    Debug.Log(item);
}

// 3. 遍历键值对
foreach(KeyValuePair<int, string> item in dic)
{
    Debug.Log("键:" + item.Key + "值:" + item.Value);
}

LinkedList

这是一个双向链表数据结构,它位于 System.Collections.Generic 命名空间中。

通过一系列节点(每个节点包含一个值和两个引用:一个指向前一个节点,一个指向后一个节点)来组织数据。这使得在 LinkedList<T> 中插入或删除元素通常比 List<T> 更高效,尤其是在列表的开头或中间位置进行操作时。

1. LinkedList的声明

LinkedList<string> list = new LinkedList<string>();

2. LinkedList的添加

// 1. 在头部添加
list.AddFirst("unity");
// 2. 在尾部添加
list.AddLast("shader");
// 3. 在某一个节点后面添加
LinkedListNode<string> nowNode = list.Find("unity");
list.AddAfter(nowNode, "hahha");
// 4. 在某一个节点前面添加
list.AddBefore(nowNode, "xixii");

3. LinkedList的删除

// 1. 移除指定结点
list.Remove("unity");
// 2. 移除头结点
list.RemoveFirst();
// 3. 移除尾结点
list.RemoveLast();
// 4. 清空链表
list.Clear();

4. LinkedList的查找

// 1. 查找头结点
LinkedListNode<string> nowNode = list.First;
// 2. 查找尾结点
nowNode = list.Last;
// 3. 查找指定结点
nowNode = list.Find("unity");
// 4. 判断某个结点是否存在
if (list.Contains("unity"))
{
    print("链表中存在值为unity节点");
}

5. LinkedList的改变

// 先找到某个节点,再访问
list.Find("unity").Value = "unity6";

6. LinkedList的遍历

// 1. foreach遍历
foreach (var item in list)
{
    print(item); // item是值
}
// 2. 从头遍历
LinkedListNode<string> node = list.First;
while (node != null)
{
    print(node.Value);
    node = node.Next;
}
// 3. 从尾遍历
node = list.Last;
while (node != null)
{
    print(node.Value);
    node = node.Previous;
}