Java.use(better);

前の記事次の記事
Java.use(better);


Episode#09

クロージャーの代用表現 -- 配列と別れる50の方法


《関連記事》

■ UML2.0/OCL に準拠する

UML2.0/OCL に準拠するコレクション操作を実現することを前提に話を進めます。

abstract class OCLCollection {
  abstract public List iterate(
    Iterate method, List acc);
  public List collect(final Collect method) {
    ...
  }
  public List select(final Select method) {
    ...
  }
}

抽象クラス OCLCollection では、3つの操作 iterate/collect/select を用意します。メソッド collect/select は、抽象メソッド iterate に帰着します。抽象メソッドを利用すると、特定のコレクションに依存しない抽象表現ができます。抽象クラス OCLCollection を具象化するときには、メソッド iterate を実現するだけで、他のメソッド collect/select を利用できます。

さらに、コレクション操作を規定するインターフェースが必要です。

interface Iterate {
  public List call(List acc, int value);
}
interface Collect {
  public int call(int value);
}
interface Select {
  public boolean call(int value);
}

どのインターフェースも、それと同じ名前の操作を規定します。インターフェースを実現する具象クラスでは、メソッド call を使って具体的な処理を実現します。

□ collect 操作を実現する

メソッド collect を実現するときには、抽象メソッド iterate を利用します。

  public List collect(final Collect method) {
    return iterate(new Iterate() {
      public List call(List acc, int value) {
        acc.add(method.call(value));
        return acc;
      }},
      new Vector());
  }

iterate の第1引数には、インターフェース Iterate に準拠するインスタンスを指定します。また、第2引数には、新たに生成するコレクションの初期値(要素を含まない空のコレクション)を指定します。

まず、メソッド call の本体では、第2引数 value を介して、コレクションの各要素を参照できます。そこで、メソッド collect の引数に指定したメソッド method を呼び出すときに、各要素 value を指定すると、その操作を施した結果 method.call(value) が得られます。

次に、メソッド call の本体では、第1引数 acc を介して、新たに生成するコレクションを参照できます。そこで、操作を施して得られた結果を、コレクションの要素として順に追加 add します。

□ collect 操作を利用する

九九の表を作成する例題を使って、collect 操作の理解を深めます。

  static void tips_table_collect() {
    List seq = range(1,9);
    for (final int n: seq) {
      List s = new Sequence(seq).collect(
      new Collect() {
        public int call(int e) { return e*n; }
      });
      for (int e: s)
        System.out.print(String.format("%2d ", e));
      System.out.println();
    }
  }
  ...
 1  2  3  4  5  6  7  8  9 
 2  4  6  8 10 12 14 16 18 
 3  6  9 12 15 18 21 24 27 
 4  8 12 16 20 24 28 32 36 
 5 10 15 20 25 30 35 40 45 
 6 12 18 24 30 36 42 48 54 
 7 14 21 28 35 42 49 56 63 
 8 16 24 32 40 48 56 64 72 
 9 18 27 36 45 54 63 72 81

1 から 9 までの数列 seq を用意します。collect 操作を利用して、seq の各要素を2倍、3倍、…とした新たな数列を生成すると、九九の表が完成します。

インターフェース Collect に準拠する、無名クラスのインスタンスを用意するときに、メソッド call の本体で各要素 e を n 倍するだけです。このとき、n の値は、1 から 9 まで順に変化します。

 ↑ TOP

》作業中です《

update*13/02/02 19:20:24