HashSet のご紹介
皆さんこんにちは
Tech Ed DEMO フォロー第2段ということで、今回は .NET Frmework 3.5 から追加される新しい Collection である HashSet についてご紹介したいと思います。
この HashSet は重複のない要素を格納する Collection で順序性は保証されません。ここでいう重複のない要素とは、Stack 上の値の Hash 値での比較になります。つまり、 Struct の場合は保持する値が同じであれば同じ値になりますが、Class の場合インスタンスが異なれば保持する値が同じ値でも HashSet 上では異なる値になるので、注意が必要です。既存のクラスで言うと、HashTable や Dictionary のキーと同じしくみです。
下記のコードでは重複のないランダムな整数を出力するプログラムです。 Random クラスで生成した乱数は重複が存在するので、重複をチェックしていますが、※の部分で HashSet に Add するときに重複の有無が確認できます。List などではわざわざ Contains で確認してから Add することになるわけですが、その必要がなくなりました。
public static void GenerateRandList()
{
for (int i = 0; i < 10; i++)
{
int gen = GenerateNum();
Console.WriteLine(gen);
}
}
private static int GenerateNum()
{
HashSet<int> record = new HashSet<int>);
Random rand = new Random(DateTime.Now.Second);
int gen;
do
{
gen = rand.Next(10);
} while (!record.Add(gen));//※ここで重複確認をしています。
return gen;
}
また、Struct の場合と Class の場合の結果の違いを示すコードを書きに書いておきます。
private static void TryHashSet()
{
//構造体(struct)の場合
HashSet<DateTime> hsForStruct = new HashSet<DateTime>();
long dtlong = DateTime.Now.Ticks;
DateTime dt1 = new DateTime(dtlong);
DateTime dt2 = new DateTime(dtlong);
hsForStruct.Add(dt1);
Console.WriteLine("Structで同じ値の異なるインスタンスは{0}", hsForStruct.Add(dt2))
//クラス(class)の場合
HashSet<Wrapper> hsForClass = new HashSet<Wrapper>();
Wrapper wrp1 = new Wrapper() { number = 100 };
Wrapper wrp2 = new Wrapper() { number = 100 };
hsForClass.Add(wrp1);
Console.WriteLine("Classで同じ値の異なるインスタンスは{0}", hsForClass.Add(wrp2));
}
//サンプルで使用しているクラス定義
class Wrapper { public long number { get; set; } };
お時間があるときにお試しください。次回は WCF の新機能についてご紹介したいと思います。