天天看點

groovy 閉包基礎 1. groovy中閉包基礎知識2. Groovy閉包的使用

1. groovy中閉包基礎知識

閉包其實就是一段代碼塊,在使用時和方法很類似,可是與方法有較大的差别。

主要包括閉包概念,閉包參數以及閉包傳回值。

1.1 閉包的定義和調用

簡單閉包定義:

def clouser = {println 'hello groovy'}
clouser.call()
//clouser()
           

輸出結果:

hello groovy
           

1.2 閉包參數

定義有參數的閉包,需要使用->,在->之前是參數,->之後是閉包體。

def clouser = {String name ->println "hello ${name}"}
//clouser.call('groovy')
clouser('groovy')
           

輸出結果:

hello groovy
           

如果有多個參數,使用逗号隔開。

def clouser = {String name, int age ->
    println "hello ${name}, age is ${age}"}
clouser('groovy', 4)
           

輸出結果:

hello groovy, age is 4
           

任意閉包有一個預設參數,不需要顯示申明,用it表示。

def clouser = {
    println "hello ${it}"}
clouser('groovy')
           

輸出結果:

hello groovy
           

如果不想閉包中有it這個隐式參數,隻需要定義一個顯示參數,這樣閉包就沒有it這個隐式參數了。

1.3 閉包傳回值

正常流程下,使用return傳回

def clouser = {
    return  "hello ${it}"
}
def result = clouser('groovy')
println result;
           

輸出結果:

hello groovy
           

閉包一定會有傳回值,預設傳回最後一句代碼的結果

def clouser = {
    println "hello ${it}"
}
def result = clouser('groovy')
println result
           

輸出結果:

hello groovy
null
           

2. Groovy閉包的使用

閉包用途非常多,這裡列舉閉包常用的4個方面:

2.1 與基本類型的結合使用

Groovy增加了upto和downto函數來進行循環。 

int x = fab(5)
println x
int y = fab(5)
print y

int fab(int number) {
    int result = 1
    1.upto(number, { num -> result *= num})
    return result
}

int fab2(int number) {
    int result = 1
    number.downto(1) {
        num -> result *= num
    }
    return result
}
           

輸出結果:

120
120
           

m.upto(n) 方法是從m開始循環到n,步長是1,循環n-m次。

m.downto(n) 方法是從m開始循環到n,步長是-1,循環m-n次。

如果閉包作為方法參數最後一個,可以寫在括号體内,也可以寫在括号體外,兩種寫法效果一樣。

還有一個常用的方法n.times()方法, 表示循環n次,循環變量it從0開始到n結束

int x = cal(5)
println x

int cal(int number) {
    int result = 0
    number.times {
        num ->
            result += num
    }
    return  result
}
           

輸出結果:

10
           

還有其他與基本類型使用的方法,具體可以從DefaultGroovyMethods.java中檢視,閉包參數可以從源碼檢視,具體檢視它調用閉包的時候有沒有傳入參數,定義的閉包需要比對方法傳入的參數。

3.2 與String結合使用

Groovy字元串提供了each()方法來進行周遊,傳回值是字元串本身。代碼:

String str = 'the 2 and 3 is 5'
str.each {
    String temp -> print temp
}
           

輸出結果:

the 2 and 3 is 5
           

通過find()方法進行查找,find方法閉包必須傳回一個布爾類型的值,滿足條件時将會作為find方法的傳回,它隻查找第一個滿足條件的值。

String str = 'the 2 and 3 is 5'
println str.find {
    String s -> s.isNumber()
}
           

輸出結果:

2
           

findAll()方法,查找所有滿足條件的字元,用法和find()方法一樣

String str = 'the 2 and 3 is 5'
def list = str.findAll {
    String s -> s.isNumber()
}
println list.toListString()
           

輸出結果:

[2, 3, 5]
           

經常使用的還有any()和every()方法,any()方法表示字元串是否含有滿足條件的字元。

String str = 'the 2 and 3 is 5'
def result = str.any {
    String s -> s.isNumber()
}
println result
           

輸出結果:

true
           

表示字元串裡面還有數字字元。

every()方法表示字元串中是否每個字元都滿足條件,如果是,傳回true,否則傳回false。

String str = 'the 2 and 3 is 5'
def result = str.every {
    String s -> s.isNumber()
}
println result
           

輸出結果:

false
           

collect()方法,表示将字元串每個元素都應用于閉包,閉包會産生一個新的結果,然後将結果添加到List中進行傳回。

String str = 'the 2 and 3 is 5'
def list = str.collect {
    it.toUpperCase()
}
println list
           

輸出結果:

[T, H, E,  , 2,  , A, N, D,  , 3,  , I, S,  , 5]
           

繼續閱讀