第7講:「ClassTableWriter」を拡張する |
その1 「ClassTableWriter」を拡張してテキストファイルからの入力による「時間割」の作成を可能にする |
ここでは「ClassTableWriter」を完全版「時間割表示システム」に対応できるように拡張します。そのためには、まずはじめ扱うデータを「1日分の時間割」から(1週間分の)「時間割」に変更する必要があります。ここでは「時間割」のプログラム上での表現方法とその利用法を解説します。つぎに、データの入力先をキーボードからテキストファイルへと変更します。そのほうがユーザーにとってデータファイルを作成しやすいからです。ここではあらかじめ用意されたテキストファイルを読み込む方法を学習します。それらを学んだ後に、実際のプログラムの書き換えを行います。 |
(1)「時間割」の表現方法とその利用法 完全版「時間割表示システム」の扱うデータは<時間割>です。第2講で行った定義によると、<時間割>とは<1日分の時間割>5つの集合体のことでした。 この<時間割>をプログラム上で表現するにあたっては、<1日分の時間割>と同様にVectorを用いることにします。すなわち<時間割>用のVectorを一つ用意し、その中に以下の図のように<1日分の時間割>を5つ格納するわけです。
Vectorはどのようなクラスのインスタンスでも格納できます。Vectorクラスのインスタンスを格納することも可能です。ここに格納されているそれぞれの<1日分の時間割>には、いままでのように<授業の情報>が5つ格納されています。
このとき、時間割Vectorの部屋番号(「インデックス」と呼ばれる)の0〜4は月曜日〜金曜日に、1日分の時間割Vectorのインデックス0〜4はそれぞれ1時限目〜5時限目という風に、インデックスと格納されるデータの順序にきちんとした対応関係が成り立つようにしてあれば、後々のデータの利用が非常にうまくゆきます。 この<時間割>を作成するための手順は、<1日分の時間割>のそれを応用します。全体を示せば以下のようになるでしょう。
このとき、<1日分の時間割>の作成は、従来の方法(「繰り返し文」を利用して5つの<授業の情報>を<1日分の時間割>のVectorに収める)をそのまま当てはめればよいのです。 またデータの利用の際には、先程述べたインデックスとデータの秩序の対応関係をうまく利用し、「elementAt」メソッドによって情報を取り出してくればよいのです。例えば「金曜、3限」の<授業の情報>を必要とする場合には、以下の手順で取り出せばよいのです。仮に<授業の情報>Vectorのインスタンス名を「week」とすると、
こうすれば「ct」には「金曜、3限」の<授業の情報>が代入されます。 |
(2)テキストファイルを読み込む方法 これまでは「1日分の時間割」を作成するために、それを構成する「授業の情報」のひとつひとつをキーボードから入力する必要がありました。もしもこれを1日分ではなく、1週間分の「時間割」に拡張する場合、この方式でデータを入力するのは大変です(例えばタイプミスをした場合、現在のClassTableWriterでは変更がききません)。そこで、あらかじめ1週間分の「授業の情報」として必要な事項をテキストファイルで作成・保存しておき、キーボードの代わりにそのファイルを入力先として、データの入力を行えると非常に便利になります。 そこで、以下のようなテキストファイルの内容を読み込む方法を紹介します。
用意するテキストファイルには、以上のように月曜1限から金曜5限に至る「授業の情報」を、「時限、改行、科目名、改行、教室名、改行」と各項目に必ず改行を挟みながら入力しておきます。そして、このテキストファイルからデータの入力を行えるよう「ClassTableWriter」を作り直します。
キーボード入力をテキストファイル入力に変更するためには「BufferedReader」のインスタンス化の際の記述を以下のように変更します。 キーボード入力準備の際の、「BufferedReader」インスタンス化の記述:
テキストファイル入力準備の際の、「BufferedReader」インスタンス化の記述:
「BufferedReader」は文字列型のデータを1行読み込む「readLine」というメソッドを持っていました。これまでの説明では、インスタンス化の際の()内の記述によって読み込み先が決まるということでした。ここではもう少し詳しくこれらの記述について説明しておきます。 まず「インスタンス化の際の()内」に記述されているのは、メソッドの場合と同様「引数」です。上記の場合、引数として「new クラス名()」が記述されている点は、キーボード入力・テキストファイル入力ともに共通しています。このような形式の記述は、まず最初に「new クラス名()」として書かれているクラスのインスタンス化を行い、その結果できあがったインスタンスを直接「BufferedReader」のインスタンス化のための引数として渡す、という意味を持っています。つまり、キーボード入力ならばまず最初に「InputStreamReader」のインスタンス化を、テキストファイル入力ならば最初に「FileReader」のインスタンス化を、それぞれ実行して、その結果を引数として「BufferedReader」のインスタンスが生成されるわけです。 これらはそれぞれ、以下の命令の短縮形だったのです。
入力先がキーボードなのかテキストファイルなのかの違いは、「InputStreamReader」と「FileReader」の違いとして考えることができるのです。「InputStreamReader」はインスタンス化の際に引数として「System.in」という特殊なデータを取ります。これはJavaにおいて「標準入力(すなわち、キーボード入力)」を表すデータです。この「InputStreamReader」のインスタンスが、文字列型データの入力を可能にします。それに対して「FileReader」はインスタンス化の引数として文字列型で「ファイル名」を要求します。この「FileReader」のインスタンスは、ここで渡されたファイル名を持つファイルからの文字列型データの入力を可能にします。 その後のデータ読み込みの手順はキーボード入力の場合もテキストファイル入力の場合も全く同様です。すなわち「BufferedReader」をインスタンス化し、「readLineメソッド」によって文字列型のデータとして「時限」「科目名」「教室名」をそれぞれ1行ずつ読み込んで「ClassTable」の属性に代入してゆけばよいのです。 |
(3)ClassTableWriterの拡張 以上の知識を総合して、「ClassTableWriter」の拡張を行います。今回は細かい手順についてのヒントを出さずに、拡張のポイントだけをまとめておきます。それを参考にトライしてみて下さい。
|
リンク: <全体のトップページ> | <第7講のトップページ> |-------------------------| <第7講・その1> <第7講・その2>