System.Collections.Generic 名前空間にあるコレクションクラス群

集合
同じ型のデータをまとめて扱うのに、基本は配列ですが、固定長という使いずらさがあります。

System.Collections名前空間にある各コレクションクラスでは、可変長で扱えましたが型の情報が欠落するためキャストが必要という使いずらさがあります。

System.Collections.Specialized

System.Collections.Specialized名前空間には、文字列に特化したStringCollection、StringDictionaryというクラスがあります。
キャスト無しに文字列型として使うことが出来ます。

using System.Collections.Specialized;

StringCollection stringCollection = new StringCollection();
stringCollection.Add("Red");
//stringCollection.Add(100); 文字列型以外はコンパイルエラー
string value1 = stringCollection[0]; //キャスト不要

StringDictionary stringDictionary = new StringDictionary();
stringDictionary.Add("a", "used before a noun to refer to a single thing");
//stringDictionary.Add(1, "number"); 文字列型以外はコンパイルエラー
string value2 = stringDictionary["a"]; //キャスト不要
こういう実装があるのならint型やDateTime型や独自定義した型の専用コレクションが欲しくなります。
そこで、コレクション生成時に型情報を指定することによりその型専用とする方式がジェネリクスです。

System.Collections.Generic

可変長のコレクションで、生成時に型情報を指定することによりキャスト不要で扱えるようにしています。

ここでは文字列型を指定する例を挙げています。キャスト無しで扱えることが確認できます。

実際には参照型でも値型でも何でも指定できます。

なお、QueueはQueue、StackはStackですが、ArrayListはList、HashtableはDictionaryが対応しています。
using System.Collections.Generic;

// ArrayList は  List<T>
List<string> list = new List<string>();
//list.Add(100);  // 文字列型は追加不可(コンパイルエラー)
list.Add("Red");
list.Add("Blue");
list.Add("Yellow");
list.RemoveAt(1);
string secondValue = list[1]; // 文字列型が返却されるのでキャスト不要
int count = list.Count; // 2

// Hashtable は Dictionary<TKey,TValue>
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("us", "United States");
dictionary.Add("jp", "Japan");
dictionary.Add("fr", "France");
string country = dictionary["jp"];      // Japan
bool isExistKey = dictionary.ContainsKey("uk"); // false

// Queue は Queue<T>
Queue<string> queue = new Queue<string>();
queue.Enqueue("AAAA");
queue.Enqueue("BBBB");
queue.Enqueue("CCCC");
string value1 = queue.Dequeue(); // AAAA 先頭の値を削除し取得
string value2 = queue.Peek();    // BBBB 先頭の値を削除せず取得
string value3 = queue.Dequeue(); // BBBB 先頭の値を削除し取得

// Stack は Stack<T>
Stack<string> stack = new Stack<string>();
stack.Push("AAAA");
stack.Push("BBBB");
stack.Push("CCCC");
string value4 = stack.Pop();     // CCCC 最後の値を削除し取得
string value5 = stack.Peek();    // BBBB 最後の値を削除せず取得
string value6 = stack.Pop();     // BBBB 最後の値を削除し取得

HashSet

有限集合に対する各種操作を高パフォーマンスで実現できます。
これは非ジェネリックに該当するものはありません。

using System.Collections.Generic;

HashSet<int> setA1 = new HashSet<int>{ 1, 2, 3, 4, 5 };
HashSet<int> setA2 = new HashSet<int>{ 1, 2, 3, 4, 5 };
HashSet<int> setA3 = new HashSet<int>{ 1, 2, 3, 4, 5 };
HashSet<int> setA4 = new HashSet<int>{ 1, 2, 3, 4, 5 };
HashSet<int> setB0 = new HashSet<int>{ 1, 3, 5, 7, 9 };

// 和集合
setA1.UnionWith(setB0); // 1,2,3,4,5,7,9
// 両方に含まれるもの
setA2.IntersectWith(setB0); // 1,2,3
// Bに含まれないもの
setA3.ExceptWith(setB0); // 2,4
// 対称差
setA4.SymmetricExceptWith(setB0); // 2,4,7,9
// 他にもあるよ

LinkedList

可変長配列であるListと同じようなものです。

N番目の値を取得するのは遅いですが、値の追加が速いという特徴があります。

Sortedシリーズ

SortedDictionary,SortedList,SortedListがあります。

追加や削除など変更時に並べ替えをするので遅くなるが、値を取り出す際は並べ替えられているので速くなる。

変更が少ない大量のデータを扱う場合は有利になる。
集合
スポンサーリンク
C#プログラミング再入門