|
- 目次
- コレクションって何?
- 汎用コレクション型
- ArrayList
- Queue
- Stack
- Hashtable
|
|
複数のオブジェクトを 1 つのグループにまとめたものです。 このようなコレクションはいろいろなケースで使いたくなるはずなので、使い方を覚えておくとわざわざ自分でクラスを作らずにすむので、便利。 どのようなコレクションを使えばよいのかは、MSのヘルプを参照してください。
|
|
汎用コレクションには、次のような一般的な種類のデータ コレクションがあります。
汎用コレクション | 定義 |
Array | public abstract class Array :
ICloneable, IList, ICollection, IEnumerable |
ArrayList | public class ArrayList : IList,
ICollection, IEnumerable, ICloneable |
Queue | public class Queue :
ICollection, IEnumerable, ICloneable |
Stack | public class Stack :
ICollection, IEnumerable, ICloneable |
Hashtable | public class Hashtable :
IDictionary, ICollection, IEnumerable,
ISerializable, IDeserializationCallback, ICloneable |
SortedList | public class SortedList :
IDictionary, ICollection, IEnumerable, ICloneable |
注意: スレッドセーフではない!
詳細は、MSのヘルプを参照してください。
コレクションのインスタンスは、基本的にスレッドセーフではありません。確実にスレッドセーフにするには、Synchronized
メソッドで返されるラップされたインスタンスに対してオペレーションする必要があります。
コレクションのエニュメレーションは、ほかのスレッドがそのコレクションを変更する可能性があるため、本質的にスレッド
セーフな処理ではありません。そのような場合には、例外が発生します。エニュメレーションを確実にスレッド
セーフにするには、エニュメレーション中にコレクションをロックするか、例外をキャッチする必要があります。
|
|
この例では、MyObject という適当なクラスつくり、複数のインスタンスを ArrayList
myArrayList に格納しています。 格納した各要素を foreach 、および MoveNext でアクセスしています。
foreach は、コレクション型をサポートしているので、foreach で各要素にアクセスできます。 また、GetEnumerator をサポートしているので、IEnumerator インターフェースの
MoveNext()メソッドでも各要素にアクセスできます。
using System;
using System.Collections;
namespace ArrayList
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// ArrayList に入れるクラス定義
/// </summary>
public class MyObject
{
public int x;
public int y;
public string str;
public MyObject(int xx, int yy, string s)
{
x = xx;
y = yy;
str = s;
}
}
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
System.Collections.ArrayList myArrayList = new System.Collections.ArrayList();
myArrayList.Add(new MyObject(1,2, "Hello"));
myArrayList.Add(new MyObject(22,33, "World"));
myArrayList.Add(new MyObject(333,444, "Hello World"));
foreach(MyObject myObj in myArrayList)
{
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
}
// IEnumerator を使ってアクセスできる。
System.Collections.IEnumerator myEnumerator = myArrayList.GetEnumerator();
while ( myEnumerator.MoveNext() )
Console.WriteLine( "{0}, {1}, {2}",
((MyObject)myEnumerator.Current).x,
((MyObject)myEnumerator.Current).y,
((MyObject)myEnumerator.Current).str );
Console.ReadLine();
}
}
}
結果は、このようになります。
|
|
この例では、MyObject
という適当なクラスつくり、複数のインスタンスを Queue.Enqueue()で格納しています。 Queue.Dequeue() でQueue から取り出せます。
また、GetEnumerator をサポートしているので、IEnumerator インターフェースの
MoveNext()メソッドでも各要素にアクセスできます。
using System;
using System.Collections;
namespace Queue
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// ArrayList に入れるクラス定義
/// </summary>
public class MyObject
{
public int x;
public int y;
public string str;
public MyObject(int xx, int yy, string s)
{
x = xx;
y = yy;
str = s;
}
}
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
System.Collections.Queue myQueue = new System.Collections.Queue();
myQueue.Enqueue(new MyObject(1,2, "Hello"));
myQueue.Enqueue(new MyObject(22,33, "World"));
myQueue.Enqueue(new MyObject(333,444, "Hello World"));
MyObject myObj = null;
myObj = (MyObject)myQueue.Dequeue();
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
myObj = (MyObject)myQueue.Dequeue();
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
myObj = (MyObject)myQueue.Dequeue();
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
Console.WriteLine();
PrintValues(myQueue);
Console.ReadLine();
}
// IEnumerator を使ってアクセスできる。
public static void PrintValues( IEnumerable myCollection )
{
System.Collections.IEnumerator myEnumerator = myCollection.GetEnumerator();
while ( myEnumerator.MoveNext() )
{
MyObject myObj = (MyObject)myEnumerator.Current;
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
Console.WriteLine();
}
}
}
}
Queue なので、FIFO になります。したがって、結果はキューに入れたとおりの順番で出力されます。 また、データを Dequeue でキューから取り除きますから、それぞれ1回づつプリントされることになります。
|
|
この例では、MyObject
という適当なクラスつくり、複数のインスタンスを Stack.Push()で格納しています。 Stack.Pop() で Stack から取り出せます。 また、Stack.Peek() で、Stack から取り除くことなくオブジェクトを取得することができます。
また、GetEnumerator をサポートしているので、IEnumerator インターフェースの
MoveNext()メソッドでも各要素にアクセスできます。
using System;
using System.Collections;
namespace Stack
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// ArrayList に入れるクラス定義
/// </summary>
public class MyObject
{
public int x;
public int y;
public string str;
public MyObject(int xx, int yy, string s)
{
x = xx;
y = yy;
str = s;
}
}
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
System.Collections.Stack myStack = new System.Collections.Stack();
myStack.Push(new MyObject(1,2, "First"));
myStack.Push(new MyObject(22,33, "Second"));
myStack.Push(new MyObject(333,444, "Third"));
MyObject myObj = null;
myObj = (MyObject)myStack.Pop();
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
myObj = (MyObject)myStack.Pop();
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
myObj = (MyObject)myStack.Peek();
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
Console.WriteLine();
myStack.Push(new MyObject(4444,5555, "Fourth"));
PrintValues(myStack);
Console.ReadLine();
}
// IEnumerator を使ってアクセスできる。
public static void PrintValues( IEnumerable myCollection )
{
System.Collections.IEnumerator myEnumerator = myCollection.GetEnumerator();
while ( myEnumerator.MoveNext() )
{
MyObject myObj = (MyObject)myEnumerator.Current;
Console.WriteLine( "{0}, {1}, {2}", myObj.x, myObj.y, myObj.str);
}
}
}
}
この例では Stack なので、FILO になります。したがって、結果はスタックに入れた時の逆順で出力されます。 また、データを Dequeue でキューから取り除きますから、それぞれ1回づつプリントされることになります。 ただし、この例では 1,2,First の時に Peek () で Stack から取り除いてないので、1,2,First
は2回プリントされています。
|
|
この例では、Key と Value のオブジェクトのペアを myHashTable.Add(Key,
Value)で格納しています。 hashtable["Key"] で、Key, Value ペアの Value を取り出すことができます。
また、GetEnumerator をサポートしているので、IEnumerator インターフェースの
MoveNext()メソッドでも各要素にアクセスできます。
using System;
using System.Collections;
namespace Hashtable
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
System.Collections.Hashtable myHashTable =
new System.Collections.Hashtable();
myHashTable.Add("Second", 2);
myHashTable.Add("First", 1);
myHashTable.Add("Third", 3);
Console.WriteLine( "{0}, {1}", "First", myHashTable["First"]);
Console.WriteLine( "{0}, {1}", "Second", myHashTable["Second"]);
Console.WriteLine( "{0}, {1}", "Third", myHashTable["Third"]);
Console.WriteLine();
PrintValues(myHashTable);
Console.ReadLine();
}
// IEnumerator を使ってアクセスできる。
public static void PrintValues( System.Collections.Hashtable myHashTab )
{
System.Collections.IDictionaryEnumerator myEnumerator =
myHashTab.GetEnumerator();
while ( myEnumerator.MoveNext() )
{
Console.WriteLine( "{0}, {1}",
myEnumerator.Key, myEnumerator.Value);
}
}
}
}
この例では"Key"に一致するものを取得することができます。したがって、結果は指定した順番で出力することができます。 最初の3つは、First, Second, Third の順番に取り出したもので、その順番になっています。 次の3つは、MoveNext() で取り出したものなので、順番は 2,1,3 で入れたにもかかわらず、3,2,1 の順で出力されています。 これは、"Key" のハッシュ値でハッシュテーブルに格納されている(はず)なので、入力順番に出力されるとは限らない。
|