Java.use(better);

Java.use(better);


Episode#03
拡張可能な for 文(2)-- for と別れる50の方法


《関連記事》

入れ子になったリスト(多重リスト)

 ̄話を戻して…。2次元配列に代えて、入れ子になったリストを利用します。

// case #3: Java - 入れ子になったリスト
List> seq2 = new Vector>();
int n = 10;
for (int i = 1; i < n; i++) {
  List seq = new Vector();
  for (int j = 1; j < n; j++) {
    seq.add(i*j);
  }
  seq2.add(seq);
}

ここでも、初期値の設定には2重の for ループが必要単純なシーケンスを扱うだけなので、コードが簡潔で見通しも良くなります。また、この制御構造は、他のデータ構造にも対処できます。
、各要素の出力にも同じ制御構造が必要です。

for (List seq: seq2) {
  for (int e: seq) {
    System.out.print(String.format("%2d ", e));
  }
  System.out.println();
}
System.out.println();

 ̄ここで注目に値するのは「入れ子になったリストに呼応する、多重の for 文」です。同じ制御構造を何度も記述するのは面倒なだけでなく、コードが煩雑で見通しも悪くなります。また、要求仕様の変更(データ構造の改変)には柔軟に対処できないので、ソフトウエア開発の能率も悪くなります。

 ̄この問題を解決するために、拡張 for 文を利用して各要素を巡回できる、新たなクラス Multiplication を用意します。すると、

int c = 0;
for (int e: new Multiplication(seq2)) {
  c++;
  System.out.print(String.format("%2d ", e));
  if (c%9 == 0) System.out.println();
}

入れ子になったリスト seq2 をシーケンスとして扱えるので、同じ制御構造を再利用できます。つまり、データ構造に依存しない「抽象表現」が可能です。同じ制御構造を何度も記述する必要がないので、コードが簡潔で見通しも良くなります。というのも、拡張 for 文は、異なるデータ構造を統一的に扱う「ポリモフィズム」を体現しているからです。

 ̄これは、次のように実現します。

class Multiplication implements Iterable {
  Iterator> it;
  Iterator cur;
  public Multiplication(List> seq) {
    it = seq.iterator();
    cur = it.next().iterator();
  }
  public Iterator iterator() {
    return new Iterator() {
      public boolean hasNext() { 
        boolean hasnext = cur.hasNext();
        if (hasnext) return true;
        else if (it.hasNext()) {
          cur = it.next().iterator();
          return hasNext();
        }
        return false;
      }
      public Integer next() {
        if (hasNext()) return cur.next();
        return null;  // NoSuchElementException
      }
      public void remove() {}
    };
  }
}

 ̄メソッド hasNext では、入れ子になったリストに呼応して、再帰的にメソッド hasNext を呼び出します。すると、while 文に頼らなくても、同等のコードを記述できます。

 ↑ TOP

》作業中です《

update*13/01/10 19:25:00