📅  最后修改于: 2020-11-04 06:46:33             🧑  作者: Mango
闭包是简短的匿名代码块。它通常只跨越几行代码。方法甚至可以将代码块作为参数。他们本质上是匿名的。
以下是一个简单闭包及其外观的示例。
class Example {
static void main(String[] args) {
def clos = {println "Hello World"};
clos.call();
}
}
在上面的示例中,代码行-{println“ Hello World”}被称为闭包。可以使用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
下一个插图重复了前面的示例并产生了相同的结果,但显示了可以使用称为它的隐式单个参数。这是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方法接受一个闭包作为参数。让我们看一下如何在这些数据类型中使用闭包的示例。
以下示例显示了闭包如何与列表一起使用。在下面的示例中,我们首先定义一个简单的值列表。然后,列表收集类型定义了一个名为的函数。每个。此函数将闭包作为参数,并将闭包应用于列表的每个元素。
class Example {
static void main(String[] args) {
def lst = [11, 12, 13, 14];
lst.each {println it}
}
}
当我们运行上面的程序时,我们将得到以下结果-
11
12
13
14
以下示例显示了闭包如何与Maps一起使用。在下面的示例中,我们首先定义一个简单的键值项映射。然后,地图集合类型定义一个名为.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}
}
}
上面的示例显示了闭包中使用的条件if(num%2 == 0)表达式,该表达式用于检查列表中的每个项目是否可被2整除。
当我们运行上面的程序时,我们将得到以下结果-
1
2
3
4
The list will only display those numbers which are divisible by 2.
2
4
闭包本身提供了一些方法。
Sr.No. | Methods & Description |
---|---|
1 | find()
The find method finds the first value in a collection that matches some criterion. |
2 | findAll()
It finds all values in the receiving object matching the closure condition. |
3 | any() & every()
Method any iterates through each element of a collection checking whether a Boolean predicate is valid for at least one element. |
4 | collect()
The method collect iterates through a collection, converting each element into a new value using the closure as the transformer. |