HashSet基础概念

HashSet是System.Collection.Generic命名空间下的HashSet<T>类,是一个高性能且无序的集合

因为HashSet是无序的,所以它不能做排序操作,又不能像数组那样索引。在HashSet上只能使用foreach来进行迭代,而无法使用for循环

HashSet中的元素不重复(可以存放单一的null),即具有元素唯一性,若向HashSet中插入重复元素,其内部会忽视此次操作,不会报出异常。因此若想拥有一个具有唯一值的集合,HashSet将会是一个具有超高检索性能的极佳选择。

1
2
3
4
5
6
7
8
9
10
11
static void Main(string[] args)
{
HashSet<string> hashSet = new HashSet<string>();
hashSet.Add("A");
hashSet.Add("B");
hashSet.Add("C");
hashSet.Add("D");
hashSet.Add("D");
Console.WriteLine("The number of elements is: {0}", hashSet.Count);
Console.ReadKey();
}

输出结果就是ABCD,最后一个重复的D被忽略了。

HashSet的一些常用方法

Contains方法

确认HashSet是否含有某元素

1
hashset.contains("D");

Remove方法

在HashSet中移除某元素

1
hashset.Remove(item);

Clear方法

删除HashSet里面的所有元素

isProperSubsetOf方法

判断HashSet是否为某一集合的完全子集

1
2
3
4
5
6
7
HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D" };
HashSet<string> setB = new HashSet<string>() { "A", "B", "C", "X" };
HashSet<string> setC = new HashSet<string>() { "A", "B", "C", "D", "E" };
if (setA.IsProperSubsetOf(setC)) //是子集输出1,不是输出0
Console.WriteLine("setC contains all elements of setA.");
if (!setA.IsProperSubsetOf(setB))
Console.WriteLine("setB does not contains all elements of setA.");

UnionWith方法

将HashSet集合合并

1
2
3
4
5
6
7
8
HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E" };
HashSet<string> setB = new HashSet<string>() { "A", "B", "C", "X", "Y" };
setA.UnionWith(setB);
foreach(string str in setA)
{
Console.WriteLine(str);
}
//最终setA的输出结果是ABCDEXY

IntersectWith方法

求两个HashSet集合的交集

1
2
setA.IntersectWith(setB);
//输出结果是setA和setB集合中都有的元素ABC

ExceptWith方法

两集合的减法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
HashSet<int> lowNumbers = new HashSet<int>();
HashSet<int> highNumbers = new HashSet<int>();

for (int i = 0; i < 6; i++)
{
lowNumbers.Add(i);
}

for (int i = 3; i < 10; i++)
{
highNumbers.Add(i);
}

Console.Write("lowNumbers contains {0} elements: ", lowNumbers.Count);
DisplaySet(lowNumbers);

Console.Write("highNumbers contains {0} elements: ", highNumbers.Count);
DisplaySet(highNumbers);

Console.WriteLine("highNumbers ExceptWith lowNumbers...");
highNumbers.ExceptWith(lowNumbers);

Console.Write("highNumbers contains {0} elements: ", highNumbers.Count);
DisplaySet(highNumbers);

void DisplaySet(HashSet<int> set)
{
Console.Write("{");
foreach (int i in set)
{
Console.Write(" {0}", i);
}
Console.WriteLine(" }");
}

/* This example provides output similar to the following:
* lowNumbers contains 6 elements: { 0 1 2 3 4 5 }
* highNumbers contains 7 elements: { 3 4 5 6 7 8 9 }
* highNumbers ExceptWith lowNumbers...
* highNumbers contains 4 elements: { 6 7 8 9 }
*/

此方法的时间复杂度是O(n),n是ExceptWith (other)中参数other的元素数

SymmetricExceptWith方法

相当于先求两个HashSet的UnionWith,再求两个HashSet的IntersectWith,然后求UnionWith和InterectWith的ExceptWith。即两个HashSet集合都不全有的元素

1
2
3
4
5
6
7
8
HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E" };
HashSet<string> setB = new HashSet<string>() { "A", "X", "C", "Y" };
setA.SymmetricExceptWith(setB);
foreach (string str in setA)
{
Console.WriteLine(str);
}
//对于这个示例,最终输出结果是BDEXY