Groovy-クロージャー
クロージャは、短い匿名のコードブロックです。通常、数行のコードにまたがっています。メソッドは、コードのブロックをパラメーターとして受け取ることもできます。それらは本質的に匿名です。
以下は、単純なクロージャの例とその外観です。
class Example {
static void main(String[] args) {
def clos = {println "Hello World"};
clos.call();
}
}
上記の例では、コード行-{println "HelloWorld"}はクロージャと呼ばれます。この識別子によって参照されるコードブロックは、callステートメントで実行できます。
上記のプログラムを実行すると、次の結果が得られます-
Hello World
クロージャの仮パラメータ
クロージャには、Groovyのメソッドと同じように、より便利にするための仮パラメータを含めることもできます。
class Example {
static void main(String[] args) {
def clos = {param->println "Hello ${param}"};
clos.call("World");
}
}
上記のコード例では、クロージャーがパラメーターを受け取るようにする$ {param}の使用に注意してください。clos.callステートメントを介してクロージャーを呼び出すときに、パラメーターをクロージャーに渡すオプションがあります。
上記のプログラムを実行すると、次の結果が得られます-
Hello World
次の図は、前の例を繰り返して同じ結果を生成しますが、それと呼ばれる暗黙の単一パラメーターを使用できることを示しています。ここで「it」はGroovyのキーワードです。
class Example {
static void main(String[] args) {
def clos = {println "Hello ${it}"};
clos.call("World");
}
}
上記のプログラムを実行すると、次の結果が得られます-
Hello World
クロージャと変数
より正式には、クロージャは、クロージャが定義された時点で変数を参照できます。以下は、これを実現する方法の例です。
class Example {
static void main(String[] args) {
def str1 = "Hello";
def clos = {param -> println "${str1} ${param}"}
clos.call("World");
// We are now changing the value of the String str1 which is referenced in the closure
str1 = "Welcome";
clos.call("World");
}
}
上記の例では、クロージャーにパラメーターを渡すことに加えて、str1という変数も定義しています。クロージャーは、パラメーターとともに変数も引き受けます。
上記のプログラムを実行すると、次の結果が得られます-
Hello World
Welcome World
メソッドでのクロージャの使用
クロージャは、メソッドのパラメータとしても使用できます。Groovyでは、リストやコレクションなどのデータ型に組み込まれているメソッドの多くに、パラメーター型としてクロージャーがあります。
次の例は、クロージャをパラメータとしてメソッドに送信する方法を示しています。
class Example {
def static Display(clo) {
// This time the $param parameter gets replaced by the string "Inner"
clo.call("Inner");
}
static void main(String[] args) {
def str1 = "Hello";
def clos = { param -> println "${str1} ${param}" }
clos.call("World");
// We are now changing the value of the String str1 which is referenced in the closure
str1 = "Welcome";
clos.call("World");
// Passing our closure to a method
Example.Display(clos);
}
}
上記の例では、
クロージャを引数として取るDisplayという静的メソッドを定義しています。
次に、mainメソッドでクロージャを定義し、それをパラメータとしてDisplayメソッドに渡します。
上記のプログラムを実行すると、次の結果が得られます-
Hello World
Welcome World
Welcome Inner
コレクションと文字列のクロージャ
いくつかのList、Map、およびStringメソッドは、引数としてクロージャを受け入れます。これらのデータ型でクロージャを使用する方法の例を見てみましょう。
リストでのクロージャの使用
次の例は、クロージャをリストで使用する方法を示しています。次の例では、最初に値の簡単なリストを定義しています。次に、リストコレクションタイプは、と呼ばれる関数を定義します。each。この関数は、パラメーターとしてクロージャを取り、リストの各要素にクロージャを適用します。
class Example {
static void main(String[] args) {
def lst = [11, 12, 13, 14];
lst.each {println it}
}
}
上記のプログラムを実行すると、次の結果が得られます-
11
12
13
14
マップでのクロージャの使用
次の例は、マップでクロージャを使用する方法を示しています。次の例では、最初にKeyValueアイテムの単純なマップを定義しています。次に、マップコレクションタイプは.eachという関数を定義します。この関数は、パラメーターとしてクロージャを取り、マップの各キーと値のペアにクロージャを適用します。
class Example {
static void main(String[] args) {
def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"]
mp.each {println it}
mp.each {println "${it.key} maps to: ${it.value}"}
}
}
上記のプログラムを実行すると、次の結果が得られます-
TopicName = Maps
TopicDescription = Methods in Maps
TopicName maps to: Maps
TopicDescription maps to: Methods in Maps
多くの場合、コレクションのメンバー間で反復し、要素が何らかの基準を満たしている場合にのみロジックを適用したい場合があります。これは、クロージャー内の条件ステートメントで簡単に処理できます。
class Example {
static void main(String[] args) {
def lst = [1,2,3,4];
lst.each {println it}
println("The list will only display those numbers which are divisible by 2")
lst.each{num -> if(num % 2 == 0) println num}
}
}
上記の例は、リスト内の各項目が2で割り切れるかどうかを確認するために使用されるクロージャで使用されている条件付きif(num%2 == 0)式を示しています。
上記のプログラムを実行すると、次の結果が得られます-
1
2
3
4
The list will only display those numbers which are divisible by 2.
2
4
クロージャで使用されるメソッド
クロージャー自体がいくつかの方法を提供します。
シニア番号 | 方法と説明 |
---|---|
1 | find() findメソッドは、いくつかの基準に一致するコレクションの最初の値を検索します。 |
2 | findAll() クロージャ条件に一致する受信オブジェクト内のすべての値を検索します。 |
3 | any()&every() メソッドanyは、コレクションの各要素を反復処理して、ブール述語が少なくとも1つの要素に対して有効かどうかを確認します。 |
4 | collect() メソッドcollectは、コレクションを反復処理し、クロージャーをトランスフォーマーとして使用して各要素を新しい値に変換します。 |