Java.use(better);
□ 抽象クラス OCLCollection を具現する
準備が整ったので、抽象クラス OCLCollection を具現した、
class Sequence extends OCLCollection implements Expression { private Iterableitems; public Sequence(Iterable iterable) { items = iterable; }
クラス Sequence を定義します。このとき、メソッド iterate を実現するだけで、他のメソッド collect/select を利用できます。
public Listiterate( Iterate method, List acc) { for (int value: items) acc = method.call(acc, value); return acc; }
for ブロックでは、コレクションの各要素 value を順に参照しながら、第1引数に指定した操作 method を施した結果 method.call(acc,value) を第2引数に指定したコレクション acc に累積して、その結果をリターン値として返します。
□ iterate 操作を利用する
素数を求める例題を使って、iterate 操作の理解を深めます。
static Listprime(int n) { final int m = (int)Math.sqrt*1.iterate(new Iterate() { public List call(List acc, final int n) { return new Sequence(acc).select(new Select() { public boolean call(int e) { return e==n || e%n != 0; }}); }}, range(2,n)); } ... [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
インターフェース Iterate に準拠する、無名クラスのインスタンスを用意するときに、第1引数には、インターフェース Iterate に準拠する任意のインスタンスを指定して、素数でないもの削除します。また、第2引数には、n 以下の数列を指定します。
インターフェース Select に準拠する、無名クラスのインスタンスを用意するときに、メソッド call の本体では(各要素 e が n と同じでないなら)各要素 e が n の倍数かどうかを判定するだけです。
素数を求めるのに有効な「エラトステネスの篩」とは、指定した整数 n 以下の素数を求めたいときに、最初の素数 2 から始めて昇順に(それと同じ数を除いて)その倍数をすべて取り除くと、最後に素数だけが残るというものです。
call(Listacc, final int n) { return new Sequence(acc).select(new Select() { public boolean call(int e) { return (nと同じ数) || (nの倍数でないもの); }}); }}, (2からnまでの数列);
ここで注目に値するのは、エラトステネスの篩に固有の部分を除くと、残りのコードの断片は、他の問題解決にも再利用できることです。事実、同じコードの断片はすでに、偶数列を求める例題で紹介しました。
↑ TOP
》作業中です《*1:double)n); return new Sequence(range(2,m