1. 程式人生 > >Groovy筆記(6)_閉包

Groovy筆記(6)_閉包

閉包介紹

1、由{}包圍起來的程式碼塊就是閉包

    println{}  //執行該行,結果如下:

   符合格式:類$匿名內部類@hash code

   結論: 閉包是一個匿名內部類的物件。

2、也可以給閉包取名字:

   def aClosure = {

        println "Hello Closure!"

   }

    println aClosuer  //結果如下 :

呼叫閉包

1、aClosure.call()                    //使用call()呼叫閉包

2、aClosure()                          //呼叫閉包的簡寫方式,類似於方法呼叫。

結論:閉包是一個可執行的程式碼塊。

3、閉包在呼叫的時候才會執行

4、引數化閉包

    def bClosure = {

          println "Hello ${it}"

     }

    bClosure.call("clat")

    bClosure("clat")

    bClosure "clat"      //結果輸出三個: Hello clat

it 是閉包的單個隱含引數。

閉包引數

1、閉包使用顯示引數

    def cClosure = {name,address ->

           println "${name},${address}!"

    }

     cClosure("hello","clat")   // 輸出: hello, clat!

2、閉包支援預設引數

    def dClosure = {name,address="clat" -> 

           println "${name},${address}!"

    }

     dClosure("hello")          //輸出hello, clat!

閉包作用域

1、def name= "clat"

     def eClosure = {println name}

     eClosure()              //輸出: clat

     //閉包可以作為方法的引數

     def aMethod(Closure closure){

           name="escaflone"; closure()   //這裡的name只是方法的區域性變數,閉包不能訪問

     }

      aMethod(eClosure)    //輸出: clat       

      def fClosure = {

           name="Aldern" ; eClosure()   //同樣是閉包,能訪問到name(其實就是可執行片段修改了外圍的一個變數)

       }

       fClosure()                 //輸出:Aldern

閉包可以返回值

1、def gClosure={number ->

             return number*2

     }

      println gClosure(3)

閉包返回6,其中return 可以省略

閉包與集合、字串

1、閉包在Groovy中頻繁出現,但最常用於對一系列值上迭代,如列表/對映/範圍/String/File

2、閉包可以用更簡潔的方式對集合進行迭代,已經不需要Java的迭代器了

3、用each遍歷list:

     def nameList = ["clat","escaflone","Aldern"]

           nameList.each{name ->

                 prinl name + ' '

           }

     輸出 clat  escaflone  Aldern

遍歷Map,Range,GString

1、遍歷Map:

    def nameMap = [1:'clat',2:'escaflone',3:'Aldern']

    nameMap.each{name ->

         print name.key + ' ' + name.value + ' '

     }

2、遍歷Range

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

3、遍歷GString

      'clat'.each{print it +'-'}   //c-l-a-t-

閉包為引數的迭代集合的方法

1、boolean any(Closure clos)

     有一個集合元素滿足閉包條件則返回true

2、List collect(Closure clos)

     把集合每個元素用閉包轉換後返回列表

3、List clooect(Collection coll,Closure clos)

     把集合每個元素用閉包轉換後放到coll中

4、bollean every(Closure clos)

     判斷是否每個元素都滿足閉包條件

5、List findAll(Closure clos)

     從集合中找到滿足閉包條件的所有元素

6、Object find(Closure clos)

     從集合中找的滿足閉包條件的第一個元素

7、int findindexOf(Closure clos)

     從集合中找到滿足閉包條件的第一個元素的索引

8、Object inject(Object value,Closure clos)

     value 與 第一個元素傳給閉包,結果值與第二個集合元素又傳給閉包,類推。(可以用來求階乘)

9、void reverseEach(Closure clos)

     反向迭代

10、List sort(Closure clos)

     排序集合

find()方法

1、def value = [1,3,5,7,9].find{element -> element >6}

     println "Found : ${value}"    // Found : 7

2、value = [1,3,5,7,9].find{element -> element >10}

     println "Found : ${value}"    // Found: null

3、value = ["Java":21 , "Groovy" :22 , "Grails" :25].find{lang ->lang.value >21}

     println "Found : ${value}"       //Found : Groovy=22

findAll()方法

1、def values= [1,3,5,7,9].findAll{element -> element >6}

     values.each{println it}

     // 輸出:7

                9

2、values=['Java':21,'Groovy':22,'Grails':25].findAll{lang -> lang.value >21}

     values.each{prinln it}

    //輸出: Grails=25

              Groovy=22

any()與every()

1、def anyElement = [11,12,13,14].any{element -> element >12}

       //true

2、def allElement = [11,12,13,14].every{element -> element >10}

       //true

3、def anyLang= ['Java':21 ,'Groovy':22,'Grails':25].any{lang -> lang.value>30}

      // false

collect()方法

1、def list= [1,2,3,4].collect{element -> return element*element}

     //  [1,4,9,16]

2、list = (0..<5).collect{element -> 2*element }

     // [0,2,4,6,8]

3、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}"

      println "list: ${list}"

      prinltn "olderLang: ${olderLang}"

      //結果輸出   lang:['Java':23,'Groovy':24,'Grails':27]          //collect 會修改原資料

                        list:[22,23,26]

                        olderLang:[Java=23,Groovy=24,Grails=27]

inject()方法求階乘

1、def numList = [2,3,4,5]

     factorial = numList.inject(1){previous, element -> previous*element}

     // 輸出: 120

2、numList = [2,3,4,5]

     closure={previous,element -> previous*element}

     factorial = numList.inject(1,closure)

     // 輸出 120

閉包的其他特性

1、閉包可以巢狀。

     def outerClosure = {country ->

             println country

             //巢狀定義閉包,方法則不執行

             def innerClosure = {city ->

                   println city

              }

             innerClosure('shanghai')

      }

     outerClosure('china') //先列印china 再列印shanghai