導入
今回から
- 配列とコレクション
- サーチ
- ソート
- 再帰
現在主流となっているほとんどの高級言語やデータベースはこれらの仕組みをあまり意識しないで利用できるようになりました。むしろ下手に自作することは
しかしながら、
今回はその第1回目として
展開
配列からコレクションへ
どのプログラミング言語を学習する人も、ArrayList
やHashMap
といったコレクションのクラスを学習するでしょう。配列とArrayList
を比較すると、
配列
配列
配列は大変シンプルで、
最も基本的な配列の使用例を次に示します。配列の要素数を含めて宣言し、
FundamentalFor1.pde
。配列要素の設定と基本的なfor
文を使った要素の列挙String[] names = new String[4];
names[0]= "Tim Bray";
names[1] = "Brian Kernighan";
names[2] = "Jon Bentley";
names[3] = "Karl Fogel";
for(int i = 0; i < names.length; ++i){
println(names[i]);
}
上のコードは配列要素の設定に何度もnames[*] =
を入力します。これが基本であることを確認した上で、無駄な入力を省くために次のような要素の値の代入方法が用意されています。
FundamentalFor2.pde
。より簡易な配列要素の設定String names[] = {"Tim Bray", // 0番目の要素
"Brian Kernighan", // 1番目の要素
"Jon Bentley", // 2番目の要素
"Karl Fogel"}; // 3番目の要素
for(int i = 0; i < names.length; ++i){
println(names[i]);
}
さらに、for
文があります。拡張for
文を使うことで、FundamentalFor2.
のように書けます。
ExtendedFor.pde
。拡張for
文を使った配列要素の列挙String names[] = {"Tim Bray",
"Brian Kernighan",
"Jon Bentley",
"Karl Fogel"};
for(String name : names){
println(name);
}
配列のソートとサーチ
一つの名前でたくさんの値を取り扱うことができる配列は大変便利な仕組みです。しかし、
毎度必要になるのが分かっている仕事をプログラマがその度に用意するのは効率がよくありません。そこで、Arrays
が用意されています。Arrays
クラスを用いると、
ArraysSortAndSearch.pde
。配列とそのユーティリティクラスの使用例import java.util.Arrays;
String names[] = {"Tim Bray",
"Brian Kernighan",
"Jon Bentley",
"Karl Fogel"};
println("toString > " + Arrays.toString(names));
Arrays.sort(names);
println("* Sorted");
println("toString > " + Arrays.toString(names));
println("* Search");
println("Position of 'Jon Bentley' is " +
Arrays.binarySearch(names,"Jon Bentley") );
ソートやサーチについては次回以降で詳しく学習します。今回の演習では最も基本的なソートとサーチのコードを書く演習を示します。予習として取り組んでください。
コレクション
配列は変数に添字と呼ばれる番号を振ることで要素を区別しています。場合によっては添字が不要であったり余計であったりします。例えば、
また、
コレクションクラスを利用する場合の欠点は、
通常、
コレクションについて、
コレクション
(collection) (時には、 コンテナー (container) と呼ばれます) は、 効率的なアクセスのために有用な方法で、 オブジェクトを保持してまとめる入れ物です。
『プログラミング言語Java』
この意味では、
* Iterable
* Collection
* Set
* SortedSet
* TreeSet
* EnumSet
* HashSet
* LinkedHashSet
* Queue
* PriorityQueue
* LinkedList
* List
* ArrayList
* LinkedList
* Map
* SortedMap
* TreeMap
* HashMap
* LinkedHashMap
* WeakHashMap
* EnumMap
* Iterator
* ListIterator
このリストの中から代表的なクラスを2つとりあげて紹介します。
- ArrayList
ArrayListは配列のオブジェクト版です。配列に比較した最大のメリットは、
要素追加・ 削除が自由自在なことです。 ArrayListUsage.
。pde ArrayList
の使用例import java.util.Arrays; import java.util.ArrayList; import java.util.Iterator; import java.util.List; String n[] = {"Tim Bray", "Brian Kernighan", "Jon Bentley", "Karl Fogel"}; ArrayList<String> names = new ArrayList(Arrays.asList(n)); //配列と同様の方法、
添字で要素にアクセスします。 println("* Access with FOR *"); for(int i = 0; i<names.size(); ++i){ println(names.get(i)); } names.add(1,"Eliotte Rusty Harold"); // 2番目位置に要素を挿入します。 names.remove(2); // 3番目の要素を削除します。 //コレクションクラスならではの方法で要素にアクセスします。 println("* Access with ITERATOR *"); Iterator<String> it = names.iterator(); while(it.hasNext()){ println(it.next()); }- HashMap
HashMapは配列では簡単に出来ない事をあっさり実現してしまう便利なクラスです。添字の代わりに好きなデータをキー
(key) として指定します。そしてそのキーに対応する値(value) を指定します。要素の呼び出しはキーを指定するだけです。この仕組みを配列から組み上げようとすれば、ずいぶん面倒でしょう。 HashMapUsage.
pde HashMap hm = new HashMap(); hm.put("Brian Kernighan","A REGULAR EXPRESSION MATCHER"); hm.put("Karl Fogel","SUBVERSION'S DELTA EDITOR: INTERFACE AS ONTOLOGY"); hm.put("Jon Bentley","THE MOST BEAUTIFUL CODE I NEVER WROTE"); hm.put("Tim Bray","FINDING THINGS"); println("Get a Element > " + hm.get("Brian Kernighan") ); println("Get a Element > " + hm.get("Jon Bentley") );
インタフェイスの活用
さらに便利なことに、Collection
やMap
というインタフェイスを実装しています。Java言語の仕組み上、
次のスケッチのように、
MapInterface.pde
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
HashMap hm = new HashMap();
Map m;
m = hm;
m.put("Brian Kernighan","A REGULAR EXPRESSION MATCHER");
m.put("Karl Fogel","SUBVERSION'S DELTA EDITOR: INTERFACE AS ONTOLOGY");
m.put("Jon Bentley","THE MOST BEAUTIFUL CODE I NEVER WROTE");
m.put("Tim Bray","FINDING THINGS");
HashMap hm2 = new HashMap();
m = hm2;
m.put(1,123);
m.put(2,223);
m.put(3,323);
m = hm;
println("Get a Element from Interface m > " + m.get("Tim Bray") );
m = hm2;
println("Get a Element from Interface m > " + m.get(2) );
m = hm;
Set s = m.keySet();
for(Object o : s){
println("Element is " + m.get(o) );
}
m = hm2;
s = m.keySet();
for(Object o : s){
println("Element is " + m.get(o) );
}
演習
演習1(難易度:middle)
ArraysSortAndSearch.
をArrays
クラスのメソッドを使用せずに、YourArraysSortAndSearch.
としてください。
演習2(難易度:easy)
MapInterface.
のコード末尾にあるfor
ループを切り分けましょう。そして、Map
インタフェイスを実装したクラスであれば何であれ、UsefulMapInterface.
としてください。
まとめ
- 配列はシンプルで高速なアクセスが可能です。要素数が少なく、
ごく単純な操作しか必要ない場合に活用すると良いでしょう。 - コレクションは柔軟な取り扱いができるよう工夫された仕組みです。特に意味がなければ、
配列ではなくコレクションを用いましょう。
学習の確認
それぞれの項目で、
- 配列の仕組みと用途が理解できましたか?
- 理解できた。気持ちよく納得した。
- 理解できた。しかし、
今ひとつスッキリしない。 - 理解できない。
- コレクションの種類と用途を理解できましたか?
- 理解できた。
- 理解はできるがイメージがわかない。
- 理解できない。
参考文献
- 『プログラミング言語Java』
(ケン アーノルド、 デビッド ホームズ、 ジェームズ ゴスリン 著、 東京電機大学出版局) - Java言語のバイブル。通読は大変ですが、
Java言語を使う人は必携です。今回は本書の第21章を読むことを宿題にします (半分冗談です)。
- Java言語のバイブル。通読は大変ですが、
- 『Java言語で学ぶ デザインパターン入門』
(結城浩 著、 ソフトバンクパブリッシング) - デザインパターンを学ぶなら、
まず本書から。コレクションクラスに実装されたイテレータについて、 本書のイテレータパターンの節を読むと理解が深まります。
- デザインパターンを学ぶなら、