閉包是一個(gè)短的匿名代碼塊。它通??缭綆仔写a。一個(gè)方法甚至可以將代碼塊作為參數(shù)。它們是匿名的。
下面是一個(gè)簡單閉包的例子,它是什么樣子。
class Example { static void main(String[] args) { def clos = {println "Hello World"}; clos.call(); } }
在上面的例子中,代碼行 - {println“Hello World”}被稱為閉包。此標(biāo)識(shí)符引用的代碼塊可以使用call語句執(zhí)行。
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Hello World
閉包也可以包含形式參數(shù),以使它們更有用,就像Groovy中的方法一樣。
class Example { static void main(String[] args) { def clos = {param->println "Hello ${param}"}; clos.call("World"); } }
在上面的代碼示例中,注意使用$ {param},這導(dǎo)致closure接受一個(gè)參數(shù)。當(dāng)通過clos.call語句調(diào)用閉包時(shí),我們現(xiàn)在可以選擇將一個(gè)參數(shù)傳遞給閉包。
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Hello World
下一個(gè)圖重復(fù)了前面的例子并產(chǎn)生相同的結(jié)果,但顯示可以使用被稱為它的隱式單個(gè)參數(shù)。這里的'it'是Groovy中的關(guān)鍵字。
class Example { static void main(String[] args) { def clos = {println "Hello ${it}"}; clos.call("World"); } }
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Hello World
更正式地,閉包可以在定義閉包時(shí)引用變量。以下是如何實(shí)現(xiàn)這一點(diǎn)的示例。
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"); } }
在上面的例子中,除了向閉包傳遞參數(shù)之外,我們還定義了一個(gè)名為str1的變量。閉包也接受變量和參數(shù)。
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Hello World Welcome World
閉包也可以用作方法的參數(shù)。在Groovy中,很多用于數(shù)據(jù)類型(例如列表和集合)的內(nèi)置方法都有閉包作為參數(shù)類型。
以下示例顯示如何將閉包作為參數(shù)發(fā)送到方法。
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); } }
在上述示例中,
我們定義一個(gè)名為Display的靜態(tài)方法,它將閉包作為參數(shù)。
然后我們?cè)谖覀兊膍ain方法中定義一個(gè)閉包,并將它作為一個(gè)參數(shù)傳遞給我們的Display方法。
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
Hello World Welcome World Welcome Inner
幾個(gè)List,Map和String方法接受一個(gè)閉包作為參數(shù)。讓我們看看在這些數(shù)據(jù)類型中如何使用閉包的例子。
以下示例顯示如何使用閉包與列表。在下面的例子中,我們首先定義一個(gè)簡單的值列表。列表集合類型然后定義一個(gè)名為.each的函數(shù)。此函數(shù)將閉包作為參數(shù),并將閉包應(yīng)用于列表的每個(gè)元素
class Example { static void main(String[] args) { def lst = [11, 12, 13, 14]; lst.each {println it} } }
當(dāng)我們運(yùn)行上面的程序,我們將得到以下結(jié)果 -
11 12 13 14
以下示例顯示了如何使用閉包。在下面的例子中,我們首先定義一個(gè)簡單的關(guān)鍵值項(xiàng)Map。然后,映射集合類型定義一個(gè)名為.each的函數(shù)。此函數(shù)將閉包作為參數(shù),并將閉包應(yīng)用于映射的每個(gè)鍵值對(duì)。
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}"} } }
當(dāng)我們運(yùn)行上面的程序,我們會(huì)得到以下結(jié)果 -
TopicName = Maps TopicDescription = Methods in Maps TopicName maps to: Maps TopicDescription maps to: Methods in Maps
通常,我們可能希望遍歷集合的成員,并且僅當(dāng)元素滿足一些標(biāo)準(zhǔn)時(shí)應(yīng)用一些邏輯。這很容易用閉包中的條件語句來處理。
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)表達(dá)式,用于檢查列表中的每個(gè)項(xiàng)目是否可被2整除。
當(dāng)我們運(yùn)行上面的程序,我們會(huì)得到以下結(jié)果 -
1 2 3 4 The list will only display those numbers which are divisible by 2. 2 4
閉包本身提供了一些方法。
序號(hào) | 方法和描述 |
---|---|
1 | find() find方法查找集合中與某個(gè)條件匹配的第一個(gè)值。 |
2 | findAll() 它找到接收對(duì)象中與閉合條件匹配的所有值。 |
3 | any() & every() 方法any迭代集合的每個(gè)元素,檢查布爾謂詞是否對(duì)至少一個(gè)元素有效。 |
4 | collect() 該方法通過集合收集迭代,使用閉包作為變換器將每個(gè)元素轉(zhuǎn)換為新值。 |
更多建議: