C# 中的 HashSet<T>
最近项目中有一个需求是使用Excel模版批量上传数据,偶然碰到数据中有重复的值导致上传失败的问题,为了避免此种情景的再次出现,我查询了一些资料,最终决定使用 HashSet<T>
来对数据进行去重处理。
此文特意整理了HashSet<T>
的一些相关内容,以备后续再碰到时快速上手使用~
下面是对HashSet<T>
的一些整理内容:
C# 中的 HashSet<T>
HashSet<T>
是 C# 中提供的一种集合类型,位于 System.Collections.Generic
命名空间下,继承自 ICollection<T>
接口。它是一个基于哈希表实现的集合,因此具有较高的查找效率。
HashSet 的特性
1. 无序性:
○ HashSet<T>
不保持元素的插入顺序。其内部是基于哈希表实现的,元素的顺序并不固定。
2. 不允许重复元素:
○ HashSet<T>
不允许包含重复的元素。添加一个已存在的元素时,集合不会改变,且不会抛出异常。
3. 查找、添加和删除的时间复杂度:
○ 查找、添加和删除操作的平均时间复杂度为 O(1)
,这使得 HashSet<T>
在进行大规模数据操作时表现非常高效。
4. 支持集合操作:
○ HashSet<T>
提供了一些用于集合操作的方法,如并集、交集、差集等,能够方便地进行集合的数学运算。
5. 泛型支持:
○ HashSet<T>
是一个泛型集合,可以存储任何类型的元素。
6. 不支持索引访问:
○ HashSet<T>
不支持通过索引来访问其元素(没有 this[]
索引器)。如果你需要按索引访问元素,可以考虑使用 List<T>
或 Array
。
HashSet<T>
常用方法
1. Add:
HashSet<int> set = new HashSet<int>();
set.Add(1); // 返回 true
set.Add(1); // 返回 false, 不会添加重复元素
○ 向集合中添加元素。若元素已存在,则不会添加,并返回 false
。
2. Remove:
set.Remove(1); // 返回 true, 移除元素 1
○ 从集合中移除指定的元素。如果元素存在,则返回 true
,否则返回 false
。
3. Contains:
set.Contains(1); // 返回 false, 因为 1 已被移除
○ 检查集合是否包含指定的元素。如果包含,返回 true
,否则返回 false
。
4. Clear:
set.Clear(); // 清空集合
○ 移除集合中的所有元素。
5. UnionWith:
HashSet<int> set2 = new HashSet<int> { 2, 3, 4 };
set.UnionWith(set2); // 当前集合包含 1 和 2, 3, 4
○ 计算当前集合与指定集合的并集,将并集结果存回当前集合。
6. IntersectWith:
set.IntersectWith(set2); // 当前集合为交集:{2}
○ 计算当前集合与指定集合的交集,并将交集结果存回当前集合。
7. ExceptWith:
set.ExceptWith(set2); // 当前集合为差集:{1}
○ 计算当前集合与指定集合的差集,并将差集结果存回当前集合。
8. SymmetricExceptWith:
set.SymmetricExceptWith(set2); // 当前集合为:{1, 3, 4}
○ 计算当前集合与指定集合的对称差集,将对称差集结果存回当前集合。
9. Count:
int count = set.Count; // 获取集合的元素个数
○ 获取集合中元素的数量。
10. CopyTo:
● 将 HashSet<T>
的元素复制到一个数组中。
int[] array = new int[set.Count];
set.CopyTo(array); // 将集合的元素复制到数组
使用场景
1. 去重操作:
HashSet<int> numbers = new HashSet<int> { 1, 2, 2, 3, 3, 4 };
// numbers 将只包含 { 1, 2, 3, 4 }
○ 如果你需要确保集合中没有重复的元素,可以使用 HashSet<T>
。例如,在处理用户输入、从列表中去重时,可以利用其自动去重的特性。
2. 集合操作:
○ 当你需要对多个集合进行交集、并集、差集等操作时,HashSet<T>
提供了方便且高效的方法。例如,在处理权限集合时,交集可以表示共同的权限,差集可以表示独有的权限。
3. 高效查找:
○ 如果需要频繁进行元素查找(是否包含某个元素),HashSet<T>
是一个理想的选择,具有 O(1)
的查找时间复杂度。
4. 从大量数据中找出独特值:
○ 在处理大量数据时,HashSet<T>
可以有效地从中找出独特的值。例如,去重用户的电子邮件地址或从日志中提取唯一事件。
5. 避免重复数据:
○ 如果你有一个动态的数据流并且想要存储其中的唯一元素,HashSet<T>
也非常适合。例如,存储访问过的页面、注册过的用户等。
示例代码
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// 创建一个 HashSet 集合
HashSet<int> set = new HashSet<int>();
// 添加元素
set.Add(1);
set.Add(2);
set.Add(3);
set.Add(1); // 不会添加重复元素
// 判断元素是否存在
Console.WriteLine(set.Contains(1)); // 输出 true
Console.WriteLine(set.Contains(4)); // 输出 false
// 移除元素
set.Remove(2);
// 打印集合的元素
foreach (var item in set)
{
Console.WriteLine(item); // 输出 1, 3
}
}
}
总结
● HashSet<T>
是一个基于哈希表的集合,提供高效的查找、添加和删除操作。
● 它的主要特性是不允许重复元素,且不保证元素的顺序。
● 适用于去重、集合操作和高效查找等场景。