Java.use(better);
《目的》
OOP の障害となる「配列」の隘路を確認した後で、Map を利用して問題解決を図るとともに、配列の「添字式」を抽象化して「ポリモフィズム」を促進する術を紹介します。
《動機》
Java は、純粋な OOP を目指すのではなく、SP との中庸を選択しました。そのため「配列」が混在すると、すべてを OOP の枠組みで統一的に扱うのが困難です。複雑なデータ構造を配列で実現するのは面倒なだけでなく、コードが複雑で見通しも悪くなるので、避けたいものです。たとえば、連想配列は、写像(キーと値の組)を扱うのに便利です。それを容易にする Map が、クラスライブラリーとして、言語仕様の一部として提供されると、ソフトウエア開発の能率が上がります。
添字式を抽象化すると、異なる種類のオブジェクトに有効な「ポリモフィズム」を実現できます。すると、要求仕様の変更にも柔軟に対処できるので、ソフトウエア開発の能率が上がります。
■ 配列の隘路
ソースコードに含まれる英文字(アルファベット)の度数分布表(ヒストグラム)を作成する事例で話を進めます。
組み込みのデータ構造の中から、この問題解決に必要なのは、任意の要素を管理できる「配列」です。そこでは、固定された境界条件を満たすときだけ、特定のデータにアクセスできるという流れに沿って、アルゴリズムが確定します。
実行すると、次の結果が得られ、
src/Source.java @: 623 A: 54 B: 5 C: 37 D: 16 E: 103 ... X: 4 Y: 7 Z: 0 [1425]
度数が最も多い英文字は 'E' だと分ります。実行したコードの断片に着目します。
for (String line: new Source(pathname)) for (String token: new ExTokenizer(line)) histo.addAll(token); System.out.println(pathname); System.out.println(histo);
ExTokenizer は、Episode#01 で紹介しました。ソースコードの各行 line からトークン token を取り出すときに、拡張 for 文が使えるので、コードが簡潔で見通しも良くなります。
これは、次のように実現します。
class Histogram1 ... protected final char lowerLimit = '@'; protected final char upperLimit = 'Z'; private int[] values = new int[size]; void add(char c) { int index = c - lowerLimit; if (c <= lowerLimit || upperLimit < c) { index = 0; } values[index] += 1; }
'A' から 'Z' までの文字を、配列の先頭からのオフセット値 index に換えて、配列の添字に指定します。たとえば、文字 'C' のオフセット値は 'C'-'@' になるので、その度数を values[3] に集計します。それ以外の文字なら、その度数を配列の先頭 values[0] に集計します。
配列を扱うときに問題となるのは、添字の範囲を超えないような配慮が必要になることです。たとえば、if に続く条件式などが、その典型です。そのため、コードが複雑で見通しも悪くなるだけでなく、バグの温床になりがちです。
↑ TOP
》作業中です《♪ 三が一(みつがいち)