コレクション
コレクションとは
すでに学んだとおり、大量のデータを扱うときには、配列を使いました。しかし、配列には一つ欠点があります。それは、あらかじめ、格納するデータの数が決まっていることです。しかし、場合によっては、あらかじめどれだけのデータを格納するかわからない時があります。その時便利なのが、Collection(コレクション)です。
Collectionは、様々なデータ群を扱うクラス群です。ネームスペース「System.Collections.Generic」に含まれています。したがって、この中のクラスを使うためには、以下の宣言をする必要があります。
System.Collections.Genericの利用「using」以下に、使用するクラス群が存在するネームスペースを記述します。前述のように、Collectionクラスは、「System.Collections.Generic」にあるので、この宣言が必要です。
List
サンプルプログラム
Collectionには、様々なクラスが存在しますが、手始めに、一番使用頻度の高い、List(リスト)クラスを使用する簡単なサンプルを紹介しましょう。以下のサンプルを入力し、実行してみてください。
プロジェクトSampleEx601/Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SampleEx601 { class Program { static void Main(string[] args) { List<int> a = new List<int>(); // 値を順に挿入 a.Add(3); a.Add(2); a.Add(1); // 1番目に4を挿入 a.Insert(1, 4); for(int i = 0; i < a.Count ; i++){ Console.WriteLine("a[{0}]={1} ", i,a[i]); } } } }
a[1]=4
a[2]=2
a[3]=1
Listの宣言と生成
Listは、配列に似たCollectionのクラスです。配列との違いは、長さを自由に変えられることと、データを途中に挿入できる点にあります。利用方法は、以下のようになります。
Listの宣言と生成型/クラスには、int,double…といったような基本データ型や、任意のクラスを指定できます。このサンプルでは、int型のListを生成しています。生成した段階では、Listは、大きさが0のデータが何も入っていない配列になります。
Listへのデータの追加
生成したListクラスにデータを追加するためには、Add()メソッドを利用します。Addメソッドは、以下のように用います。
Addメソッドの利用15から17行目で、Listであるaには、順次、1,2,3というデータが追加されます。データには0,1,2…というインデックスがついているため、この段階で、a[0]、a[1]、a[2]には、それぞれ1,2,3というデータが格納されています。
また、Listには、すでに生成された配列の途中に、データを挿入することが可能です。それを可能にしているのが、19行目で利用されている、Insertメソッドです。Insertメソッドは、指定したインデックスの後に、データを追加することができます。
Insertメソッドの利用ここでは、1番目に値4を挿入しています。もともと1番目には、2が、2番目には3が格納されていましたが、1番目以降のデータは、この値が挿入されたために、一つずつインデックスが後ろにずれます。これにより、データのならび順は、3,4,2,1となります。(図6-1.参照)
図6-1.ListのAddメソッドと、Insertメソッドの働きListの出力
このようにして、代入されたデータは、配列と同じように扱うことが可能です。20行目から22行目で、aの値を出力しています。その際、20行目で、Countメソッドで、Listの中に入っているデータの数を取得し、それにより、値a[0]、a[1]、…の結果を出力しています。
Listの中のデータの削除
続いて、Listの中のデータを削除するサンプルを見てみましょう。
プロジェクトSampleEx602/Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SampleEx602 { class Program { static void Main(string[] args) { List<String> a = new List<String>(); // データを追加 a.Add("Taro"); a.Add("Hanako"); a.Add("Jiro"); a.Add("Kaoru"); // データを削除 a.Remove("Taro"); // "Taro"を削除 a.RemoveAt(1); // 1番目のデータを削除 foreach (String s in a) { Console.WriteLine(s); } } } }
Kaoru
ここでは、データを削除するメソッドとして、Removeメソッドと、RemoveAtメソッドを使用しています。Removeメソッドは、指定したデータを削除します。このサンプルでは、15行目~18行目で、データを追加しています。これにより、"Taro"、"Hanako"、"Jiro"、"Kaoru"というデータの配列が生成されます。
まず、20行目のRemove()メソッドで、"Taro"というデータが削除されます。これにより、データは、"Hanako"、"Jiro"、"Kaoru"になります。続いて、21行目のRemoveAt()メソッドで、インデックス1番目のデータを削除します。このとき、1番目のデータは"Jiro"ですから、残ったデータは、"Hanako"、"Kaoru"となるわけです。
最後に、このデータを22行目から25行目で、データをコンソール画面に出力しています。ここでは、foreachループを用いて出力しています。このように、Listのデータは、配列同様、foreachループを用いて全成分を出力することが可能です。
Listクラスの主要メソッド
なお、Listクラスには、以下のような主要なメソッドが存在します。Listクラスにはこのほかにもたくさんのメソッドがありますが、以下のものを利用すれば、たいていのことは可能です。
表5-1.ArrayListクラスの主要メソッドメソッド | 働き |
---|---|
Reverse() | 全体の要素の順序を反転させます。 |
Find() | 指定されたデータを探し、最も小さいインデックスを返します。 |
Exists() | 指定されたデータと同じものが存在するかどうかを調べます。 |
Clear() | 全てのデータを削除します。 |
Sort() | オブジェクトを並べ替えます。 |
ハッシュテーブルの利用
ハッシュテーブルとは
ハッシュテーブルは、コレクションの一種で、別名、連想記憶とも言います。これも、配列の一種ですが、通常の配列との違いは、配列が、0,1,2…といったような、数値の番号によるインデックスでデータを管理しているのに対し、キー(key)と値(value)のペアを保持しているという点にあります。
具体的な例を挙げると、たとえば、「Sunday」と言う言葉と、「日曜日」、「Monday」という言葉と「月曜日」というデータを結びつける、といったように、キーと、それを基に得られる値を関連付けた辞書のようなデータ構造がハッシュテーブルです。
サンプルプログラム
C#で、ハッシュテーブルを実現するクラスとして、Dictionaryクラスがあります。以下のサンプルを実行してみてください。
プロジェクトSampleEx603/Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SampleEx603 { class Program { static void Main(string[] args) { // 連想記憶クラスの生成 Dictionary<String, String> capital = new Dictionary<String, String>(); // データの追加 capital["日本"] = "東京"; capital["イギリス"] = "ロンドン"; capital["フランス"] = "パリ"; capital["中国"] = "北京"; Console.WriteLine("世界の首都"); foreach (String s in capital.Keys) { Console.WriteLine("{0}の首都は{1}です。",s,capital[s]); } } } }
日本の首都は東京です。
イギリスの首都はロンドンです。
フランスの首都はパリです。
中国の首都は北京です。
Dictionaryクラスの宣言と生成
Dictionaryクラスの宣言と生成は、以下のように行います。
Dictionaryクラスの宣言と利用Arrayとの違いは、キーと値の両方の型を宣言する必要があるという点です。このサンプルでは、国名とその首都の名前と言う組み合わせなので、ともにStringを用いています。このようにしてインスタンスを生成すると、配列変数のようにしてデータを設定・取得することが可能です。
Dictionaryクラスのデータの設定16行目から21行目でこの処理が行われ、国名がキーとなり、首都を値として、関係性が設定されます。(図6-2.)
図6-2.Dictionaryクラスの働き配列変数やListが、[]内にインデックスを入れて値を代入・取得しているのに対し、Dictionaryは、[]にキーを入れます。
データの出力
ハッシュテーブルは、配列とは違い、インデックスに順序や前後関係があるわけではありませんそこで、配列を用いてすべての内容を出力しようとした場合、まずはキーをすべて出力する必要があります。その処理が行われているのが、21行目です。
Dictionaryクラスのキーの取得これにより、Dictionaryクラスに与えられたキーの一覧が配列として得られます。このサンプルでは、それを利用し、すべてのキーを取得し、それに対応する値を得て、出力しているのです。
HashSet
サンプルプログラム
最後に、データを重複なく管理する方法について説明します。そのために利用するクラスが、HashSetクラスです。まずは、以下のサンプルを実行してみてください。
プロジェクトSampleEx604/Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SampleEx604 { class Program { static void Main(string[] args) { // ハッシュセットの生成 HashSet<int> t = new HashSet<int>(); // データの追加 t.Add(1); t.Add(2); t.Add(3); t.Add(1); // データの出力 foreach (int i in t) { Console.WriteLine("{0}", i); } } } }
2
3
HashSetの使用方法は、Arrayに似ています。このサンプルでは、14行目で、intのデータが入るハッシュセットを生成し、15行目から18行目のAdd()メソッドを用いてデータを追加しています。追加しているデータは、1,2,3,1なので、Arrayであれば、この順序にデータが格納されるはずです。
しかし、foreachを用いて出力したデータの結果は、1,2,3となっています。1は重複しているため、複数登録できないためです。このように、HashSetクラスは、重複なくデータを登録できます。(図6-3.)
図6-3.HashSetクラスの働きCollectionクラスは、このほかにもいくつも存在します。しかし、以上のクラスを押さえておけば、たいていのことができます。まずは、これらのクラスを上手に利用することから始めましょう。
練習問題 : 問題6.