今回は、集合と要素に関するJava言語の演習問題をふたつ用意しました。概念を確認し、Java言語の基本的な文法やクラスライブラリの使い方を練習しましょう。気軽に取り組んでみてください。
問題:集合とJava言語に関する以下の問いに答えてください。
(1)10より小さな自然数のうち、偶数を整数型の配列とArrayListのオブジェクトにセットするプログラムを作ってください。結果が得られたら、偶数の個数を表示し、その後全ての偶数を表示しましょう。
明らかに偶数は2、4、6、8の4つ[1]ですが、10より小さい偶数がいくつあるか「わからない」ものとして解いてみてください。
ArrayListを用いると、配列を用いた場合よりも何が便利になるのか考えながら問題に取り組みましょう。
(2)10より小さな自然数の集合を全体集合とし、(1)で作成した偶数の集合の補集合をとるプログラムを、配列の場合とArrayListの場合それぞれで作ってください。
(1)と同様、補集合の要素数を表示した後で各要素を表示させましょう。なお、偶数の集合はあらかじめ与えられているものとし、コード中に埋め込みましょう。
解説
(1)10より小さな自然数のうち、偶数を整数型の配列とArrayListのオブジェクトにセットするプログラムを作ってください。結果が得られたら、偶数の個数を表示し、その後全ての偶数を表示しましょう。
先ずは配列で目的の処理を行ってみます。
解説は後回しにして、ArrayListを用いて同じことをさせてみます。
実質半分以下に行数が減りました。キーボードを打つ数が減ります。
どちらが良いかというより、「どちらが目的に合うか」で配列とArrayListをはじめとするクラス群の使い分けが必要です。今、もし短くてわかりやすいプログラムを作ることが最優先であるとしましょう。その視点でコードをながめると、配列を使用した場合のコードGusuNoHairetsu.javaには次のような短所があります。
- 一時的なデータの保存場所として、7行目の配列tempが使われる。
- 偶数の数をカウントするために変数evenが使われる。
- 繰り返しが3回行われる。
ArrayListクラスを用いることで、繰り返しの数は2回に減りました。計算に1回、表示に1回と目的に応じた最低限の回数です(※2)。
配列を用いた場合「10以下の偶数の個数がわからない」という前提ですから、偶数を格納する配列のサイズがあらかじめ決定できません。探索が完了した段階で、発見した偶数の個数に合った配列を宣言し、格納しています。配列の長さをその場その場で変更できない(「静的である」といいます)ので生じた不便です。
一方、ArrayListはあらかじめサイズを指定しなくても、データを追加するたびに増えてくれますし、削除すれば減ってくれます(「動的である」といいます)。
メモリの使用量、アクセス速度において配列の方がArrayListよりも利がありますが、ArrayListをはじめとするクラス群を使うことでプログラムがシンプルになり、トータルでのメモリの節約や実行速度の向上が望めます。何よりも、コードが読み下しやすくなる利点は得難いものです。
(2)10より小さな自然数の集合を全体集合とし、(1)で作成した偶数の集合の補集合をとるプログラムを、配列の場合とArrayListの場合それぞれで作ってください。
先ず、配列を用いた場合を紹介します。少々冗長ですが、読み下しやすく組みました。短くしようと思えば、もっと短くなります。題意に反しないように、可読性を損なわないように、短く書く訓練の題材にしてみると良いでしょう。今回、全体集合と偶数の集合をあらかじめ与えています。2つの集合に重複する要素がないかを逐一チェックし、重複がなければ補集合の要素であるとして保管させています。
次にArrayList を用いた場合を示します。
トータルで10行しか違いませんが、補集合をとる処理と表示をしているところに注目すると、18行あったものがたったの6行になりました[3]。
せっかくArrayListクラスを使ったのですから、イテレータを紹介しておきます。イテレータは、ArrayListDeHoshugo.java中では、カウンタに用いた変数iの代わりになるものです。「逐次参照を楽にする道具」と覚えましょう。ArrayListDeHoshugo.javaでは、添字もあわせて最後に出力していますので、イテレータを用いない方がシンプルになりました。しかし、Java言語を用いた多くのプログラムではArrayListをはじめとするコレクションクラスで逐一データを参照処理する際にイテレータを用いています。単純にデータを取り出すことのみに特化しているため、コードをシンプルに書ける利点があるのです。
コード例を次に示しますので参考にしてください。GusuNoArrayList.javaをイテレータを用いて書き直してみます。
4行目でimportするクラスの末尾が*(アスタリスク)になったのは、イテレータを利用するためにArrayListに加えてListクラス(インターフェイス)が必要だからです。逐一書くと次のように2行にわたってキーパンチしなければなりません。
ワイルドカードであるアスタリスクを用いて一行で済ませたのです。(※4)。