闭包是一个短的匿名代码块。它通常跨越几行代码。一个方法甚至可以将代码块作为参数。它们是匿名的。
一、利用闭包输出Hello Groovy
package study
//方式一:
class GroovyClosureGrammar {
public static void main(String[] args) {
def closure = {
println "Hello Groovy"
}
closure()
}
}
//方式二:
{
println "Hello Groovy"
}()
//方式三:
def closure = {
println "Hello Groovy"
}
closure.call()
二、闭包中的形式参数
//方式一:
class GroovyClosureGrammar {
public static void main(String[] args) {
def closure = {
params->println "Hello Groovy $params"
}
closure(2020)
}
}
//方式二:
{
println "Hello Groovy $it"
}("2020")
//方式三:
def closure = {
params -> println "Hello Groovy $params"
}
closure.call(2020)
三、在方法中使用闭包
class MethodWithClosure {
def static Display(clo) {
clo.call("Groovy");
}
static void main(String[] args) {
def str1 = "Hello";
def clos = { param -> println "${str1} ${param}" }
clos.call("World"); //Hello World
str1 = "Welcome";
clos.call("World"); //Welcome World
//str1会跟随clo传入Display中
MethodWithClosure.Display(clos);//Welcome Groovy
}
}
四、匿名内联函数,基本相关类型Api
package closure
/**
* 匿名内联函数,也称为一个闭包。
* 基本类型相关的API
*/
int x = fab(5)
//阶乘
int fab(int number) {
int result = 1;
1.upto(number, { num -> result *= num })
return result
}
println x;
//阶乘
int fab2(int number) {
int result = 1
number.downto(1) {
num -> result *= num
}
return result
}
println fab2(5)
int sum(int number) {
int result = 0;
number.times {
num ->
{
println(num)
result += num;
}
}
return result
}
println sum(5)
输出结果:
![](https://i-blog.csdnimg.cn/blog_migrate/6231afe2f35f5a6a1d672d26cc4cd288.png#pic_center)
五、String 相关API
package closure
/**
* 和String相关的API
*/
String str="2 and 3 is 5"
//each遍历
str.each {
String s->print s.multiply(2)
}
println()
//find查找符合条件的第一个字符
println str.find{
String s->s.isNumber()
}
//findAll 查找符合条件的所有字符
def list=str.findAll{
String s-> s.isNumber()
}
println list.toListString()
//any 查找是否存在符合条件的字符
def result=str.any{
String s->s.isNumber()
}
println result
//every查找是否所有字符都符合条件
def result1=str.every{
String s->s.isNumber()
}
println result1
//对str的每一位单独操作后的结果保存到一个集合中
def list2=str.collect{
it.toUpperCase()
}
println list2.toListString()
输出结果:
![](https://i-blog.csdnimg.cn/blog_migrate/78bf1942676510bb9b8b963a80915c08.png#pic_center)
六、关于Closure的this、owner、delegate理解
package study
/**
* Groovy的闭包程序
*/
{
println "Hello Groovy"
}()
def scriptClosure = {
/**
* study.GroovyClosureGrammar02@750fe12e
* study.GroovyClosureGrammar02@750fe12e
* study.GroovyClosureGrammar02@750fe12e
*/
println this //代表闭包定义处的类,此时这个闭包是定义在GroovyClosureGrammar02这个类中
println owner //代表闭包定义处的类或者闭包对象,此时这个闭包是定义在GroovyClosureGrammar02这个类中
println delegate //代表任意对象,delegate默认为owner指向的对象
}
scriptClosure.call()
println "============================"
class Person {
def static classClosure = {
println "classClosure:" + this //classClosure:class study.Person 静态闭包,指向当前类
println "classClosure:" + owner //classClosure:class study.Person 静态闭包,指向当前类
println "classClosure:" + delegate //代表任意对象,delegate默认为owner指向的对象
println "============================"
}
/**
* 方法内定义闭包
* @return
*/
def static innerClosure() {
def classClosure = {
println "innerClosure classClosure:" + this //innerClosure classClosure:class study.Person 静态闭包,指向当前类
println "innerClosure classClosure:" + owner //innerClosure classClosure:class study.Person 静态闭包,指向当前类
println "innerClosure classClosure:" + delegate //代表任意对象,delegate默认为owner指向的对象
}
classClosure.call()
}
}
Person.classClosure()
Person.innerClosure()
println "===================="
def outerClosure = {
println "outerClosure:" + this
//outerClosure:study.GroovyClosureGrammar02@26f143ed 代表闭包定义处的类,此时这个闭包是定义在GroovyClosureGrammar02这个类中
println "outerClosure:" + owner
//outerClosure:study.GroovyClosureGrammar02@26f143ed 代表闭包定义处的类,此时这个闭包是定义在GroovyClosureGrammar02这个类中
println "outerClosure:" + delegate //代表任意对象,delegate默认为owner指向的对象
def innerClosure = {
/**
* innerClosure:study.GroovyClosureGrammar02@26f143ed
* innerClosure:study.GroovyClosureGrammar02$_run_closure2@1f9d6c7b
* innerClosure:study.GroovyClosureGrammar02$_run_closure2@1f9d6c7b
*/
//innerClosure:study.GroovyClosureGrammar02@26f143ed 代表闭包定义处的类,此时这个闭包是定义在GroovyClosureGrammar02这个类中
println "innerClosure:" + this
//innerClosure:study.GroovyClosureGrammar02$_run_closure2@1f9d6c7b 代表闭包定义处的类或者闭包对象,此时这个闭包是定义在GroovyClosureGrammar02这个类中的outerClosure闭包中
println "innerClosure:" + owner
//代表任意对象,delegate默认为owner指向的对象
println "innerClosure:" + delegate
}
innerClosure.call()
}
outerClosure.call()
println "================================"
Person person = new Person()
def outPersonClosure = {
def innerPersonClosure = {
/**
* this代表闭包定义处的类,此时这个闭包是定义在GroovyClosureGrammar02这个类中
* owner代表闭包定义处的类或者闭包对象,此时这个闭包是定义在outPersonClosure这个对象中
* delegate代表person
* innerPersonClosure:study.GroovyClosureGrammar02@1af1347d
* innerPersonClosure:study.GroovyClosureGrammar02$_run_closure3@c827db
* innerPersonClosure:study.Person@377c68c6
*/
println "innerPersonClosure:" + this
println "innerPersonClosure:" + owner
println "innerPersonClosure:" + delegate
}
//讲person委托给delegate
innerPersonClosure.delegate = person
innerPersonClosure.call()
}
outPersonClosure.call()
println "================================"
class Children {
String name
def pretty = {
// String name="pretty" //Closure.TO_SELF
"My name is $name"
}
String toString() {
pretty.call()
}
}
def children = new Children(name: 'Groovy')
class Parent {
String name
}
def parent = new Parent(name: 'Gradle')
//将parent委托给children
children.pretty.delegate = parent
//闭包委托策略
children.pretty.resolveStrategy = Closure.TO_SELF
/**
* 不设置闭包委托策略
* My name is Groovy
* 设置闭包委托策略 Closure.DELEGATE_FIRST //优先从delegate寻找
* My name is Groovy
* 设置闭包委托策略 Closure.DELEGATE_ONLY //只从delegate寻找
* My name is Gradle
* 设置闭包委托策略 Closure.OWNER_FIRST //优先从owner寻找
* My name is Groovy
* 设置闭包委托策略 Closure.OWNER_ONLY //只从owner寻找
* My name is Groovy
* 设置闭包委托策略 Closure.TO_SELF //从闭包内部去找,例如闭包{a},就是从闭包{a}中寻找对应属性
* My name is pretty
*/
println children.toString()