19.2.8 HashSet<T>

HashSet<T>类主要是设计用来做高性能的集运算的,例如对两个集合求交集、并集、差集等。集合中包含一组不重复出现且无特定顺序的元素。

在.NET Framework 4.0中,BCL中新添加了ISet<T>接口,该接口提供了对集(Set)的抽象。HashSet<T>类实现了ISet<T>接口。该类的类图如图19-18所示。

HashSet<T>的一些特性如下:

❑HashSet<T>中的值不能重复且没有顺序;

❑HashSet<T>的容量会按需自动增加。

然后,我们了解一下HashSet<T>类的构造函数,并对每个构造函数进行说明,它共有5个构造函数。

❑public HashSet():使用集类型的默认相等比较器创建一个空的新实例;

❑public HashSet(IEnumerable<T>collection):使用集类型的默认相等比较器创建一个新实例,并把指定集合collection中的数据复制到集中;

19.2.8 HashSet<T> - 图1

图 19-18 HashSet<T>的类图

❑public HashSet(IEqualityComparer<T>comparer):使用指定的相等比较器comparer创建一个空的新实例;

❑public HashSet(IEnumerable<T>collection,IEqualityComparer<T>comparer):使用指定的相等比较器comparer创建一个新实例,并把指定集合collection中的数据复制到集合中;

❑protected HashSet(SerializationInfo info,StreamingContext context):使用序列化数据初始化HashSet<T>类的新实例。

因为HashSet<T>是专门设计用来做集合运算的,因而它提供的方法中有不少是和集合运算相关的,表19-10是它的一些常用方法介绍。

19.2.8 HashSet<T> - 图2

在代码清单19-13中,我们演示了使用3种不同的构造函数实例化HashSet<T>对象,尤其需要注意的是set3使用自定义的相等比较器。

代码清单19-13 HashSet<T>的代码示例


using System;

using System.Collections.Generic;

namespace ProgrammingCSharp4

{

class CollectionSample

{

public static void Main()

{

HashSet<string>set1=new HashSet<string>();

set1.Add("a");

set1.Add("b");

set1.Add("c");

HashSet<string>set2=new HashSet<string>(new string[]{"c","d","e"});

HashSet<string>set3=new HashSet<string>(new MyComparer<string>());

set3.Add("a");

set3.Add("c");

set3.Add("f");

PrintSetInfo(set1,"set1");

PrintSetInfo(set2,"set2");

PrintSetInfo(set3,"set3");

set1.ExceptWith(set2);

Console.WriteLine(“从set1集合中移除set2集合中包含的元素(差集)……”);

PrintSetInfo(set1,"set1");

set2.IntersectWith(new string[]{"a","c"});

Console.WriteLine(“set2集合仅包含数组(a、c)中也存在的元素(交集)……”);

PrintSetInfo(set2,"set2");

}

public class MyComparer<T>:EqualityComparer<T>

{

public override bool Equals(T x,T y)

{

if(x==null)

{

if(y==null)

{

return true;

}

else

{

return false;

}

}

else

{

if(y==null)

{

return false;

}

else

{

return x.Equals(y);

}

}

}

public override int GetHashCode(T obj)

{

return obj.GetHashCode();

}

}

private static void PrintSetInfo(HashSet<string>sampleList,string varName)

{

Console.Write("{0}:",varName);

foreach(string val in sampleList)

{

Console.Write("\t{0}",val);

}

Console.WriteLine();

Console.WriteLine("Count:{0}",sampleList.Count);

}

}

}


上述代码的运行结果为:


set1:a b c

Count:3

set2:c d e

Count:3

set3:a c f

Count:3

从set1集合中移除set2集合中包含的元素(差集)……

set1:a b

Count:2

set2集合仅包含数组(a、c)中也存在的元素(交集)……

set2:c

Count:1

请按任意键继续……


图19-19演示了上述代码中涉及集合运算的部分。

19.2.8 HashSet<T> - 图3

图 19-19 集合间的运算示意图