はじめMath! Javaでコンピュータ数学

第30回 集合の数学 集合と要素[前編]

この記事を読むのに必要な時間:およそ 3 分

ArrayListで有限集合を表現する

データの集合を取り扱う場合に便利な機能をあらかじめ装備したコレクションという仕組みがJava言語にあります。コレクションの中でもArrayListクラスは配列を拡張したものであるため,プログラミング入門者の方々には親しみやすいものだと思います。ただしArrayListに格納できるのは,プリミティブな型(intやfloat,booleanといった基本型のこと)ではなく,IntegerクラスやFloatクラスといったラッパークラスです。これはArrayListの便利さを用いるときのちょっとした制約と考えましょう。実際のソフトウエア開発では基本データ型よりも,データを取り扱うために便利な機能を付加したラッパークラスを使うことのほうが推奨されるからです※2⁠。それと同じように,生の配列を使うよりは,コレクションクラスのArrayListを用いることが推奨されます。要素の総数を増減できますし,任意の位置に挿入,任意のデータを削除することも出来るからです※3⁠。今回がいいチャンスですから,覚えておきましょう※4⁠。

サンプルコード:ArrayListDeShugo.java

01: //サンプルコード
01: //ArrayList で集合を表現する
01: //filename : ArrayListDeShugo.java
04: import java.util.ArrayList;
05: 
06: class ArrayListDeShugo {
07:   public static void main(String[] args) {
08:     ArrayList A = new ArrayList();
09:     A.add("a");
10:     A.add("b");
11:     A.add("c");
12:     A.add("d");
13:     A.add("e");
14:     for(int i=0;i<A.size();i++){
15:       System.out.println("A.get("+i+") = " + (String)A.get(i));
16:     }
17:   }// end of main
18: }// end of class ArrayListDeShugo
※1)
それまでのデータを持ったまま,配列を長くしたり,短くしたりはできないということです。
※2)
特別な意図があるときは別です。基本データ型を用いた方が良いと判断されれば,そうすればよいのです。
※3)
今回のサンプルコード:ArrayListDeShugo.javaでは,15行目に示すように,格納したデータを取り出す際,格納したデータに対応したクラスでキャストする必要があります。現在のJava言語(Java5.0以降)ではGeneric宣言が用意されています。Generic宣言を用いると,その後の代入でキャストが不要になります。ArrayListDeShugo.javaの8行目で,ArrayList<String> A = new ArrayList<String>(); と宣言します。<String>と書き加えることで,そのArrayListにはStringクラスのオブジェクトしか格納できなくなります。ソースコード中でIntegerなど他のオブジェクトを代入しようとするとコンパイルエラーになり,実行時のエラーを事前に防ぐ仕組みです。
※4)
以前のJava言語(バージョン1.2までは,ArrayListが実装されておらず,その代わりバージョン1.0からVectorクラスが利用されていました。最新版のJava言語でもVectorクラスを利用可能ですが,互換性のために渋々残っている言語要素ですので,新しくプログラムを作る場合には利用するべきではありません。

集合を表現するためのその他の手段 MapとSet

Java言語でデータの集合を取り扱う場合,配列やArrayList以外の方法として,MapSetがあります。

今回は詳細は抜きにして,紹介のみにとどめます。配列やArrayListは,格納するデータを,そのデータに振られた通し番号で管理(格納された内容の取得や再格納)します。この番号を添字といいます。それに対してMapは格納するデータに対して名前を付けます。この名前をキーといいます。名前は数値であってもよし,文字列であってもよし,場合に応じたものを選択できます。電話帳に掲載された電話番号が,その電話番号を持っている人の氏名と関係づけられているのと同じです。Setは単にデータを次々と保持します。データに関連づけられた添字やキーに当たるものはありません。データを特定するのは,そのデータの値そのものです。添字やキーが不要な場面で有効です。

問題:集合とJava言語に関する以下の問いに答えてください。

(1)穴埋め問題です。⁠あ)(い)に当てはまる正しい数値を答えてください。

コード例:AnaumeShugo.java

01: class AnaumeShugo {
02:   public static void main(String[] args) {
03:     char a[] = {’a’,’b’,’c’,’d’,’e’};
04:     for(int i=(あ);i<=(い);++i){
05:         System.out.println("a["+i+"] = " + a[i]);
06:     }
07:   }// end of main
08: }// end of class AnaumeShugo

解説

(1)穴埋め問題です。⁠あ)(い)に当てはまる正しい数値を答えてください。


(あ)= 0

(い)= 4

この問題,⁠あ)のところにゼロ,⁠い)のところに4が入ります。迷うことなく正解された方は結構。しかし,意外と失敗するのがこの配列の添字。数を数えるのに1から始めるのが人情というもの。今そこにあるものをゼロと数えるのには,なかなか抵抗があります。コンピュータのハードウエアの学習などをされた方にとっては,⁠0番地から始まるメモリのアドレス」といったことで慣れ親しんでいるものですが,ごく一般的な理系・文系の学習をされてきた方々には,最初受け入れがたいと思います。かくいう私も,よくこのミス(配列のカウントは0から※5⁠)でバグを入れたりします。ものの数は1から数えるというクセがでてしまいます。そして,n個ある配列の最後の添え字はnだ,ってね。正しくはn-1までなのに。自戒の念も込めて,ここに問題として紹介した次第。

※5)
他言語や設定によっては,配列の先頭要素の添字を1とするものがあります。例えばVBでは宣言時の添字に5を用いると,添字は0から5まで使えます。要素数が一つ多く確保されます。賛否あるところでしょうが,私は重宝しています。

今回はここまで

今回は,集合の数学での集合の定義の方法,そしてJava言語での集合の取り扱い方を紹介しました。

今回のまとめ

  • 集合の定義は,有限個数の要素をいちいち列挙する方法と,連続な範囲を指定する方法,集合に含まれるものの性質を言葉で表現する方法などがあります。
  • Java言語で集合を表現する最も基本的な方法は配列とArrayListです。

著者プロフィール

平田敦(ひらたあつし)

地方都市の公立工業高等学校教諭。趣味はプログラミングと日本の端っこ踏破旅行。2010年のLotYはRuby。結城浩氏のような仕事をしたいと妄想する30代後半♂。