- Groovy 教程
- Groovy - 首页
- Groovy - 概述
- Groovy - 环境配置
- Groovy - 基本语法
- Groovy - 数据类型
- Groovy - 变量
- Groovy - 运算符
- Groovy - 循环
- Groovy - 决策
- Groovy - 方法
- Groovy - 文件I/O
- Groovy - 可选值
- Groovy - 数字
- Groovy - 字符串
- Groovy - 范围
- Groovy - 列表
- Groovy - 映射
- Groovy - 日期和时间
- Groovy - 正则表达式
- Groovy - 异常处理
- Groovy - 面向对象
- Groovy - 泛型
- Groovy - 特性 (Traits)
- Groovy - 闭包
- Groovy - 注解
- Groovy - XML
- Groovy - JMX
- Groovy - JSON
- Groovy - DSL
- Groovy - 数据库
- Groovy - 构造器
- Groovy - 命令行
- Groovy - 单元测试
- Groovy - 模板引擎
- Groovy - 元对象编程
- Groovy 有用资源
- Groovy - 快速指南
- Groovy - 有用资源
- Groovy - 讨论
Groovy - 闭包
闭包是一个简短的匿名代码块。它通常只包含几行代码。方法甚至可以将代码块作为参数。它们本质上是匿名的。
下面是一个简单的闭包示例及其外观。
class Example {
static void main(String[] args) {
def clos = {println "Hello World"};
clos.call();
}
}
在上面的示例中,代码行 - {println "Hello World"} 被称为闭包。可以通过调用语句执行此标识符引用的代码块。
运行上述程序后,我们将得到以下结果:
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的隐式单参数。“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的静态方法,该方法接受闭包作为参数。
然后我们在主方法中定义一个闭包,并将其作为参数传递给我们的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
使用闭包与映射
以下示例显示如何将闭包与映射一起使用。在下面的示例中,我们首先定义一个简单的键值对映射。映射集合类型然后定义一个名为.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
与闭包一起使用的方法
闭包本身提供了一些方法。
| 序号 | 方法和描述 |
|---|---|
| 1 | find()
find方法查找集合中第一个匹配某些条件的值。 |
| 2 | findAll()
它查找接收对象中所有匹配闭包条件的值。 |
| 3 | any() & every()
any方法迭代集合的每个元素,检查布尔谓词对至少一个元素是否有效。 |
| 4 | collect()
collect方法迭代集合,使用闭包作为转换器将每个元素转换为新值。 |