作成日 2008/9/28 最終更新日 2008/9/28
配列
このページでは配列(特に固定長配列、可変長配列、連想配列)について説明します。
配列なんて、オブジェクト指向とあまり関係ない(オブジェクト指向以前の話)と思うかもしれません。
ですが、どのように管理しているのかぐらいは押さえておいた方がいいです。何も知らないと、オブジェクトの破棄のタイミング、オブジェクト内のデータが変更されたときの挙動が理解できないです。
オブジェクト指向とは関係ない内容となりますが、配列の使いどころについて説明します。
プログラムの設計をすると、どのようにデータを持たせるか、データとデータの関連をどうするかといったことを考えることが重要になってくることがあります(※1)。
その際、同じクラスの複数のオブジェクトをまとめて管理したいときがあります。そういうときに配列を使用します。
■1.管理したいオブジェクトの個数が決まっている場合
一般には固定長配列を使用するのが良いです(※2、※3)。
■2.管理したいオブジェクトの個数が決まっていない場合(プログラムの状況によって変化する場合)で、index(一般には0からの連番)による管理をする場合
可変長配列を使いましょう(※4)。
Javaであれば、java.util.ArrayList、java.util.Vectorなど。
VBAなら、可変長配列(※5)やCollection(※5)かな。
■3.管理したいオブジェクトの個数が決まっていない場合(プログラムの状況によって変化する場合)で、文字列などによる管理をする場合
これは、たとえば、以下のようなデータを管理したい場合です。
表1 名前によってデータを管理したい(※名前は重複しないとする)
名前
体重(kg)
身長(cm)
山田 太郎
84.93
183.42
上野 花子
49.99
158.52
だるま 太郎
108.92
169.45
土野 三郎
53.37
171.23
このような場合は連想配列を使用します(※3)。
Javaであれば、java.util.HashMapなど。
VBAであれば、Collection(※5)かDictionary(※6)を使用するのが一般的だと思います。
固定長配列でオブジェクトを管理する場合について、もう少し詳しく説明します。
■固定長配列とメモリ
そんなに難しいことではないのですが、図1のようになります。
図1 固定長配列でのオブジェクトの管理(イメージ図)
ここで重要なのは、配列ではオブジェクトそのものを管理しているわけではなく、オブジェクトの先頭アドレスを管理しているということです。このことは、オブジェクトの破棄に関係してきます(※1)。
また、ぜんぜん関係ない箇所で例えば1番目のオブジェクトのフィールド値を変更したら、配列から1番目のオブジェクトを取得しそのオブジェクトのフィールド値を取得したら、フィールドの値は変更後の値になっています。これはオブジェクトのシャローコピー(※2)の考えと同じです。
■UML2.0での表記
クラスの属性が固定長配列となっている場合は多重度(multiplicity)を使用して表記します(図2か図3のどちらでも。)。
図2 固定長配列のUML表記 その1
図3 固定長配列のUML表記 その2
-----
可変長配列はプログラム実行時にサイズが変更できる配列です。
ライブラリでクラスとして提供される場合は、一般に、要素の追加、取得、削除用のメソッドが提供されます。
■可変長配列とメモリ
固定長配列の場合とそんなに変わるわけではないです。
動的にメモリを確保(Cならmalloc関数を使用)し、そこにオブジェクトの先頭アドレスを入れていくだけです。
確保したメモリが足りなくなったら、より大きいメモリを確保し、そこに、データをコピーするだけです(※1)。
しかし、可変長配列はクラスとしてすでに用意されていることが多いので、メモリを確保、コピーなどは忘れても良いです(※2)。ただし、可変長配列のときも固定長配列と同じように、配列ではオブジェクトそのものを管理しているわけではなく、オブジェクトの先頭ポインタを管理しているということは理解しておいた方がいいです。
■UML2.0での表記
固定長配列のとき(図2,3)と同じように、多重度(multiplicity)を使用して表記します。
ただし、多重度は配列の要素数の最小値..最大値という形で書きます。最大がわからない(無限の場合)は「*」とします。
例:[4..*](要素数が4以上の場合)
[6..9](要素数が6から9の場合)
[*](要素数が0以上の場合)
■可変長配列の使用
繰り返しになりますが、すでにクラスとして用意されていることが多いです(C言語のように古い言語の場合はないのですが)。
Javaの場合は、java.util.ArrayListクラス、java.util.Vectorクラスを使うのが一般的だと思います(※3)。
VBAであれば、Collectionクラスを使うのが良いです。
-----
※1:J2SE1.4.2_12でのjava.util.ArrayListはこのような実装のようです(ソースを見ました)。
ただ、可変長配列の実装は単方向リストや双方向リストでも不可能ではありません(メモリの断片化やランダムアクセスの速度が遅いという欠点がありますが)。可変長配列のすべての実装方針がJ2SE1.4.2_12と同じだと思わないでください。それと残念ながらVBAのCollectionの実装方針はわかりませんでした。
※2:残念ながら、パフォーマンス(速度など)を特に考える必要がある場合はこの通りではないかもしれません。その場合は、マニュアルをしっかり読みましょう。
※3:java.util.ArrayListクラスとjava.util.Vectorクラスの違いは、簡単にはスレッドセーフかどうかの違いです。詳しいことはよくわかりませんが…。
連想配列はキー(文字列やオブジェクト)と値(オブジェクト)を関連付ける配列です。
■連想配列とメモリ
連想配列はハッシュテーブルにて実装されるのが一般的だと思います。とりあえず、ハッシュテーブルについてはほかで調べてください。
連想配列はクラスとしてすでに用意されていることが多いので、ハッシュテーブルなどは忘れても良いです(※1)。ただし、
連想配列のときも固定長配列と同じように、配列ではオブジェクトそのものを管理しているわけではなく、オブジェクトの先頭ポインタを管理しているということは理解しておいた方がいいです。
■UML2.0での表記
固定長配列のときと同じように、多重度(multiplicity)を使用しても良いのですが、限定子(qualifier)を使った方がわかりやすいです。
図3 連想配列のUML表記
■連想配列の使用
繰り返しになりますが、連想配列はすでにクラスとして用意されていることが多いです(C言語のように古い言語の場合はないのですが)。
Javaの場合は、java.util.HashTableクラス、java.util.HashMapクラスを使うのが一般的だと思います。
VBAであれば、Collectionクラスか、Dictionaryを使うのが良いです(※2)。
-----
※1:ただし、パフォーマンス(速度など)を特に考える必要がある場合はこの通りではないかもしれません。その場合は、マニュアルをしっかり読みましょう。
※2:繰り返しになりますが、DictionaryはMac版のExcelVBAでは使用できません。
このページを作成する際に参考にしたページなどです。
このページの利用によって発生した、いかなる損害について、このホームページの作成者は責任を負いません。
このページの間違いや嘘を見つけた方、このページに書いて欲しい情報がある方は
メール をお願いします。
Microsoft 、Windows 、Visual Basic および Excel は米国Microsoft
Corporationの米国およびその他の国における登録商標または商標です。
ここではExcel® をエクセル、Visual Basic® for Applications をVBAと表記する場合があります。
Mac 、Mac OS
、Mac OS
X は米国Apple
Computer,Inc.の登録商標または商標です。
OMG、UML、Unified Modeling Languageは、Object Management Groupの商標または登録商標です。
Sun、Sun Microsystems、サンのロゴマーク、Java、及び、Sun/Solaris/Java に関連するすべての商標およびロゴマークは米国 Sun Microsystems, Inc. の米国およびその他の国における商標または登録商標です。
その他、社名および商品名、システム名称などは、一般に各社の商標または登録商標です。
このホームページの作成者はこれらの会社とはいっさい関係がありません。