Skip to content

HashSet

csharp-hashset-deep-dive

HashSet 是什么

HashSet<T> 是“唯一元素集合”。它只关心:这个元素有没有出现过。 它不关心顺序,也不能用下标访问。

c
using System.Collections.Generic;

HashSet<int> collectedIds = new();

collectedIds.Add(1001);
collectedIds.Add(1002);
collectedIds.Add(1001); // 重复,不会再加进去

Debug.Log(collectedIds.Count); // 2

Add 的返回值很重要

c
bool isNew = collectedIds.Add(1001);

if (isNew)
{
    Debug.Log("第一次收集");
}
else
{
    Debug.Log("已经收集过了");
}

Add 返回 true:真的加进去了。 Add 返回 false:集合里已经有了。

最常用:Contains

c
if (collectedIds.Contains(1001))
{
    Debug.Log("这个宝箱已经开过");
}

如果你只是想判断“有没有”,HashSet<T> 通常比 List<T> 更合适。

Unity 常见用法

c
HashSet<Enemy> hitTargets = new();

void Hit(Enemy enemy)
{
    if (!hitTargets.Add(enemy))
        return;

    enemy.TakeDamage(10);
}

这个适合范围技能:同一个敌人进入多次,只伤害一次。

寻路也常用:

c
HashSet<Vector2Int> visited = new();

if (visited.Contains(cell))
    return;

visited.Add(cell);

集合运算

c
HashSet<int> a = new() { 1, 2, 3 };
HashSet<int> b = new() { 3, 4, 5 };

a.UnionWith(b);      // 并集:1,2,3,4,5
a.IntersectWith(b);  // 交集:双方都有的
a.ExceptWith(b);     // 差集:移除 b 里有的

注意:这些 With 结尾的方法会修改当前集合。想保留原集合,就先复制一份。

HashSet vs List vs Dictionary

List<T>:有顺序、可重复、能用下标。 Dictionary<TKey, TValue>:用 Key 找 Value。 HashSet<T>:只判断元素是否存在,并自动去重。

常见坑

不要依赖 HashSet 的遍历顺序。 不要在 foreach 当前 HashSet 时 AddRemove。 自定义类当元素时,要理解相等规则;常用 intstringenumVector2Int 会更稳。

参考链接Microsoft HashSetHashSet.AddHashSet.ContainsHashSet.UnionWithHashSet.IntersectWithIEqualityComparerUnity Script Serialization Rules

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0