Groovy闭包

本文深入探讨了Groovy中的闭包,包括其类型groovy.lang.Closure,闭包与函数的区别,以及闭包的多种用法如upto、each、find、findAll、any、every、collect、inject等方法的示例应用。此外,还介绍了闭包作为返回值的情况以及冒泡排序的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是闭包

闭包在Groovy 的类型是 groovy.lang.Closure,是Groovy的一大利器。

闭包可以视为代码块、语句块、可以访问周围范围内的所有变量或方法。

def z = { println "hello" }
z()

很简单,闭包只是一个语句,用大括号包含。您可以将其分配给变量,然后像常规方法调用一样调用此闭包。闭包具有一个默认的隐式参数,称为it。还可以提供自定义的参数。同样,就像方法中的情况一样,闭包的最后一个表达式是闭包的返回值。但是,如果您觉得可读性更高,也可以使用return关键字。

def square = { it * it }
assert square(3) == 9
def lengthThan = { String s, int i -> return s.size() > i }
//def lengthThan = { String s, int i -> s.size() > i }
assert lengthThan("FunTester", 4) == true
assert lengthThan("Fun", 6) == false

闭包和函数的区别

函数执行之后内部变量全部销毁,但是闭包不会,闭包的外部变量会一直保存。

def static add(num) {
    def sum = 0
    sum += num
    return sum
}

def static addByClosure(init) {
    def addInner = {
        inc ->
        init += inc
        init
    }
    return addInner
}

println "one call: ${add(5)}"  // one call: 5
println "two call: ${add(5)}"  // two call: 5

def addClosure = addByClosure(0)
println "one call: ${addClosure(5)}"  // one call: 5
println "two call: ${addClosure(5)}"  // two call: 10

闭包的常见用法

闭包可以这样写:

  1. def clos = {参数名 -> 代码块}
  2. def clos ={代码块}
def hello = 'Hello'
def clos = {
    param -> println "${hello},${param}"
}
def clos2 = {
    p1,p2 -> println "the parameters are ${p1} and ${p2}"
}

def exec(clo){
    clo('wzy')
}

//闭包的调用方式
clos.call('zhh')
clos('zhh')
clos'zhh'
clos2(1,2)
exec(clos)
exec clos
exec{
    param -> println "hellooo, ${param}"
}

输出结果:

Hello,zhh
Hello,zhh
Hello,zhh
the parameters are 1 and 2
Hello,wzy
Hello,wzy
hellooo, wzy

upto方法

1.upto(5){
	println"abc"
}

def count = 0
1.upto(4){
	pp -> count +=pp
}

println "count:${count}"

输出:

abc
abc
abc
abc
abc
count:10

each方法

each方法常常用于列表、映射和字符串,以遍历每个元素,并将闭包应用于每个元素

[1,2].each{
	println it
}

['zhangsan':21,'lisi':22].each{
	println it
}

['zhangsan' : 21, 'lisi' : 22].each {
	println "${it.key} maps to :${it.value}"
}

['zhangsan' : 21, 'lisi' : 23].each {
	p -> if(p.value>22){
		println "${p.key} value over 22"
	}else{
		println "${p.key} value low 23"
	}
}

输出

1
2
zhangsan=21
lisi=22
zhangsan maps to :21
lisi maps to :22
zhangsan value low 23
lisi value over 22

find方法

find方法返回集合中符合某个判断标准的第一个值,若不存在则符合null。在闭包中,集合元素使用的判断条件必须是布尔表达式。

def f = [1,2].find{
    it -> it>1
}
println "find :${f}"

输出

find :2

findAll方法

findAll方法将遍历所有元素,并返回一个符合条件的列表。

def fa = ['zhangsan':21,'lisi':23,'wangwu':24].findAll{
    it -> it.value>22
}
println "find all :${fa}"
fa.each{
    println it
}
[1,2,3].findAll{
    it -> it>1
}.each{
    println it
}

输出:

find all :[lisi:23, wangwu:24]
lisi=23
wangwu=24
2
3

any方法

any方法将遍历检查集合的每个元素,以确认:对至少一个元素来说,由闭包提供的布尔断言是否合法。

def a = [1,2].any{
	it -> it >1
}
println "any one over 1?${a}"

输出

any one over 1?true

every方法

every方法则用来检查:对集合的所有元素来首,闭包提供的布尔断言是否合法。

def a = [1,2].every{
    it -> it>1
}
println "every one over 1?${a}"

输出

every one over 1?false

collect 方法

collect方法将遍历某个集合,并使用闭包中的变换方法将集合中的每个元素转换为一个新值。返回一个由转换后的值所组成的列表。

def list = [1,2,3,4].collect{
    it -> return it * it
}
println "list: ${list}"

list = (0..2).collect{
    it -> 2 * it
}
println "list:${list}"

list = (0..<2).collect{
    it -> 3 *it
}
println "list:${list}"

def s = ['zhangsan':21,'lisi':22]
list = s.collect{
    it -> ++it.value
}
def olderS = s.collect{
    it -> ++it.value
    return it
}
println "s:${s}"
println "list: ${list}"
println "olderS: ${olderS}"

输出

list: [1, 4, 9, 16]
list:[0, 2, 4]
list:[0, 3]
s:[zhangsan:23, lisi:24]
list: [22, 23]
olderS: [zhangsan=23, lisi=24]

inject方法

inject方法可用于遍历集合,首先将需要传递的初始值和集合项目传递给闭包,此时其传递的初始值将作为初始结果,然后再和下一个集合元素一起传给闭包,以此类推。

def factorial = [2,3,4].inject(1){
    previous,element ->
    println "pre:${previous},ele:${element}"
    previous * element
}
println "facotria(4): ${factorial}"

输出

pre:1,ele:2
pre:2,ele:3
pre:6,ele:4
facotria(4): 24

闭包作为返回值

def multiply(x){
    return{
        y -> return x * y
    }
}
def twice = multiply(2)
println "twice(3) = ${twice(3)}"

输出

twice(3) = 6

冒泡排序

def swap = {
	sList, p, q ->
		def temp = sList[p]
		sList[p] = sList[q]
		sList[q] = temp
	}
def minPosition = {
	pList, from ->
		def mPos = from
		def nextFrom = from + 1
			for (i in nextFrom..<pList.size()) {
				if (pList[i] < pList[mPos]) {
					mPos = i
				}
			}
		return mPos
	}
def selectionSort = {
	l ->
		def size = l.size() - 1
		for (j in 0..<size) {
			def minPos = minPosition(l, j)
			swap(l, minPos, j)
		}
		return l
}
 
def table = [2, 4, 1, 3]
def sorted = selectionSort(table)
println "sorted : ${sorted}"

输出

sorted : [1, 2, 3, 4]

参考网上大神:https://blog.youkuaiyun.com/zhangyongfeiyong/article/details/53127092

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值