Java.use(better);
■ UML2.0/OCL
UML2.0/OCL に準拠するコレクション操作を事例に話を進めます。
□ collect 操作
collect 操作は、コレクションの各要素に処理を施した、新たなコレクションが欲しいときに便利です。たとえば、各要素を10倍にした、新たなコレクションが欲しいときには、collect 操作を利用できます。そこで、
new Sequence(range(9)).collect(new Collect() { public int call(int e) { return e*10; } })); ... [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
インターフェース Collect に準拠する、無名クラスのインスタンスを用意するときに、メソッド call の本体で各要素 e を10倍するだけです。
ここで注目に値するのは、各要素に 10 を加えたいなら、e*10 を e+10 に変更するだけです。collect 操作の利用者(プログラマー)は、新たな数列を用意したり、要素を追加する方法を知る必要がありません。各要素に対して実行 call したい処理を指定するだけです。collect 操作の提供者(プログラマー)は、新たなコレクションを用意して、処理を施した要素を追加します(後述)。
□ select 操作
select 操作は、コレクションの中からある条件を満たす要素だけを選んだ、新たなコレクションが欲しいときに便利です。たとえば、偶数だけからなる、新たなコレクションが欲しいときには、select 操作を利用できます。そこで、
new Sequence(range(9)).select(new Select() { public boolean call(int e) { return e%2 == 0; } })); ... [0, 2, 4, 6, 8]
インターフェース Select に準拠する、無名クラスのインスタンスを用意するときに、メソッド call の本体で各要素 e が偶数かどうかを判定だけです。
ここで注目に値するのは、奇数を選びたいなら、e%2==0 を e%2!=0 に変更するだけです。select 操作の利用者(プログラマー)は、新たな数列を用意したり、要素を追加する方法を知る必要がありません。各要素に対して判定 call したい条件を指定するだけです。select 操作の提供者(プログラマー)は、新たなコレクションを用意して、条件を満たす要素だけを追加します(後述)。
□ iterate 操作
iterate 操作は、コレクションの要素を使って処理した結果を累積したいときに便利です。たとえば、数列の総和が欲しいときには、iterate 操作を利用できます。そこで、
new Sequence(range(9)).iterate(new Iterate() { public Listcall(List acc, int value) { return new Vector (Arrays.asList( acc.get(0) + value)); } }, new Vector (Arrays.asList(0)))); ... [45]
インターフェース Iterate に準拠する、無名クラスのインスタンスを用意するときに、メソッド call の本体では、すでに累積した値と各要素 value の和を求めるだけです。
同様のことを Scala で実現すると、次のようになります。
scala> print( 0 to 9 ) Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) scala> print( (0 to 9).fold(0) { _+_ } ) 45
メソッド fold の引数に指定した式 _+_ は任意です。第1の変数 _ は、すでに累積した値を参照します。第2の変数 _ は、数列 0 to 9 の要素を順に参照します。そのため、残りのコードの断片は、他の目的にも再利用できます。また、Jython では、次のようになります。
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> reduce(lambda acc,e: acc+e, range(10), 0)
45
lambda に続く式 acc+e は任意です。第1引数 acc は、すでに累積した値を参照します。第2引数 e は、数列 0 to 9 の要素を順に参照します。そのため、残りのコードの断片は、他の目的にも再利用できます。
↑ TOP
》作業中です《