1. 程式人生 > >Groovy入門-閉包

Groovy入門-閉包

由{}包圍起來的程式碼塊就是閉包
println {}//執行改行,結果:類名.ClosureDemo runclosure1@10a2d64 匿名內部類@hash_code
結論一:閉包是一個匿名內部類的物件
也可以給閉包取名字:
def aClosure = {
println ‘Hello Closure!’
}
println aClosure //結果:類名[email protected]

呼叫閉包

aClosure.call() //使用call()呼叫閉包
aClosure() //呼叫閉包的簡寫方式,類似於方法呼叫
結論二:閉包是一個可執行的程式碼塊


閉包在呼叫的時候才會執行
引數化閉包:
def bClosure = {
println “Hello ${it}!”
}
bClosure.call(‘lxt008’)
bClosure(‘lxt008’)
bClosure ‘lxt008’
it是閉包的單個隱含引數

閉包引數

閉包使用顯示引數
def cClosure = { name.address ->
println “ name, {address}!”
}
cClosure(‘lxt008’,’shenzhen’) //輸出:lxt008,shenzhen!

閉包支援預設引數
def dClosure = { name,address=’shenzhen’ ->
println “

name, {address}!”
}
dClosure(‘lxt008’) //輸出: lxt008,shenzhen

閉包作用域
def name = ‘lxt008’
def eClosure = { println name }
eClosure() //輸出:lxt008

//閉包可以作為方法的引數
def aMethod(Closure closure){
name = ‘lxt007’; closure()
}
aMethod(eClosure) //輸出:lxt008

def fClosure = {
name = ‘lxt006’; eClosure()
}
fClosure() //輸出:lxt006

閉包可以返回值

def gClosure = { number ->
return number*2
}
println gClosure(3) //6 return 可省略

閉包與集合、字串

閉包在Groovy中頻繁出現,但最常見用於對一系列值上迭代,如列表、對映、範圍、String、File
閉包可以用更簡潔的方式對集合進行迭代,已經不需要Java的迭代器了。

用each遍歷list

def citysList = ['shenzhen','beijing','shanghai']
citysList.each{ city->
    println city + ' '
}                                   //shenzhen beijing shanghai

遍歷Map,Range,GString

遍歷Map:

def citysMap = [1:'shenzhen',2:'beijing',3:'shanghai']
citysMap.each{ city->
    println city.key + ' ' + city.value + ' '
}                                  //1 shenzhen 2 beijing 3 shanghai

遍歷Range:

(1..<5)each{ println it + '-' }   //1-2-3-4-

遍歷GString

'lxt008'.each{ println it + '-' } //1-x-t-0-0-8- 

閉包為引數的迭代集合的方法
boolean ang(Closure clos) 有一個集合元素滿足閉包條件則返回true
List collect(Closure clos) 把集合每個元素用閉包轉換後放到coll中
List collect(Collection coll, Closure clos) 把集合每個元素用閉包轉換後放到coll中
boolean every(Closure clos) 判斷是否每個元素都滿足閉包條件
Object find(Closure clos) 從集合中找到滿足閉包條件的第一個元素
List findAll(Closure clos) 從集合中找到滿足閉包條件的所有元素
int findIndexOf(Closure clos) 從集合中找到滿足閉包條件的第一個元素的索引
Object inject(Object value, Closure clos)value與第一個元素傳給閉包,結果值與第二個元素有傳給閉包,類推。
void reverseEach(Closure clos) 反向迭代
List sort(Closure clos) 排序集合

find()方法

def value = [1,3,5,7,9].find{ element -> element > 6}
println "Found: ${value}"               //Found:7
value = [1,3,5,7,9].find{ element -> element > 10}
println "Found: ${value}"               //Found:null
value = ['Java':21,'Groovy':22,'Grails':25].find{ lang-> lang.value > 21 }
println "Found: ${value}"               //Found:Groovy=22

findAll()方法

def values = [1,3,5,7,9].findAll{ element -> element > 6 }
values.each{ println it}                     //7 9
[1,3,5,7,9].findAll{ element -> element > 6}.each{ println it }        //7 9
values = ['Java':21,'Groovy':22,'Grails':25].findAll{ lang -> lang.value > 21 }     //Grails=25 Groovy=22

any()與every()

println '===================================='
def anyElement = [11,12,13,14].any{ element -> element > 12 }
println "anyElement:${anyElement}"                  //anyElement:true
def allElements = [11,12,13,14].every{ element -> element > 10 }
println "allElement:${allElements}"                 //allElements:true
def anyLang = ['java':21,'Groovy':22,'Grails':25].any{ lang -> lang.value > 30 }
println "anyLang:${anyLang}"                        //anyLang:false
println '==================================='

collect()方法

def list = [1,2,3,4].collect{element -> return element * element}
println "List: ${list}"                    //return 可以省略 輸出:List:[1,4,9,16]
list = (0..5).collect{ element -> 2* element }
println "list:${list}"                     //結果輸出:list:[0,2,4,6,8]
def lang = ['Java':21,'Groovy':22,'Grails':25]
list = lang.collect{ entry -> ++ entry.value }
def olderLang = lang.collect{ entry -> ++entry.value; return entry}
println "lang:${lang}"                     //lang:["Java":23,"Groovy":24,"Grails":27]
println "list:${list}"                     //list:[22,23,26]
println "olderLang:${olderLang}"           //olderLang:[Java=23,Groovy=24,Grails=27]

inject()方法求階乘

def numList = [2,3,4,5]
factorial = numList.inject(1){ previous, element -> previous * element}
println "Factorial(5):${factorial}"           //輸出:Factorial(5):120
numList = [2,3,4,5]
closure = { previous, element -> previous * element }
factorial = numList.inject(1,closure)
println "Factorial(5):${factorial}"           //輸出:Factorial:120

閉包的其他特性

//閉包可以巢狀
def outerClosure = { country->
    println country
    //巢狀定義閉包,方法則不允許
    def innerClosure = { city->
        println city
    }
    innerClosure('shenzhen')
}
outerClosure('china')                    //先列印china,後列印shenzhen