一 搭建groovy環境
安裝JDK
[root@node1 ~]# yum -y install java-11-openjdk
官網下載groovySDK下載
https://groovy.apache.org/download.html,使用最新的穩定版本3.0
[root@node1 ~]# cd /usr/local/src/
[root@node1 src]# ll
-rw-r--r-- 1 root root 73717075 May 8 09:13 apache-groovy-sdk-3.0.3.zip
[root@node1 src]# unzip apache-groovy-sdk-3.0.3.zip
[root@node1 src]# cd groovy-3.0.3/
rwxr-xr-x 2 root root 4096 Apr 7 16:22 bin drwxr-xr-x 2 root root 33 Apr 7 16:22 conf drwxr-xr-x 4 root root 63 Apr 7 16:22 doc drwxr-xr-x 2 root root 73 Apr 7 16:22 grooid drwxr-xr-x 2 root root 4096 Apr 7 16:22 indy drwxr-xr-x 3 root root 4096 Apr 7 16:22 lib -rw-r--r-- 1 root root 14895 Apr 7 16:15 LICENSE drwxr-xr-x 2 root root 267 Apr 7 16:22 licenses -rw-r--r-- 1 root root 1574 Apr 7 16:15 NOTICE drwxr-xr-x 12 root root 309 Apr 7 16:22 src
配置環境變量
[root@node1 bin]# vim /root/.bash_profile
export PATH="$PATH:/usr/local/src/groovy-3.0.3/bin/" export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.7.10-4.el7_8.x86_64/ PATH=$PATH:$HOME/bin:$JAVA_HOME/bin
[root@node1 bin]# java -version
openjdk version "11.0.7" 2020-04-14 LTS OpenJDK Runtime Environment 18.9 (build 11.0.7+10-LTS) OpenJDK 64-Bit Server VM 18.9 (build 11.0.7+10-LTS, mixed mode, sharing)
[root@node1 bin]# groovy -v
Groovy Version: 3.0.3 JVM: 11.0.7 Vendor: Oracle Corporation OS: Linux
二 Ubuntu18.04 安裝 Idea 2018.2 Ultimate
2.1 環境信息
OS:Ubuntu18.04
JDK:1.8
Idea: 2018.2 Ultimate
2.2 下載Idea 2018.2安裝
到jetbrains官網,選擇Ultimate版本的tar.gz包下載
root@darren-virtual-machine:/IDEA# pwd
root@darren-virtual-machine:/IDEA# cp /root/Downloads/ideaIU-2020.1.1.tar.gz ./
root@darren-virtual-machine:/IDEA# tar -xf ideaIU-2020.1.1.tar.gz
root@darren-virtual-machine:/IDEA# chmod 755 -R idea-IU-201.7223.91/
root@darren-virtual-machine:/IDEA# cd idea-IU-201.7223.91/
root@darren-virtual-machine:/IDEA/idea-IU-201.7223.91# cd bin/
root@darren-virtual-machine:/IDEA/idea-IU-201.7223.91/bin# ./idea.sh
使用免費的三十天的
2.3 安裝groovy環境
使用相同的方法安裝Java和groovy
root@darren-virtual-machine:/IDEA# apt-get install openjdk-8-jdk
root@darren-virtual-machine:/IDEA# cp /root/Downloads/apache-groovy-sdk-3.0.3.zip /IDEA/
root@darren-virtual-machine:/IDEA# unzip apache-groovy-sdk-3.0.3.zip
配置環境變量
root@darren-virtual-machine:/IDEA/groovy-3.0.3/bin# vi /root/.bashrc
JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64/ GROOVY_HOME=/IDEA/groovy-3.0.3/ PATH=$PATH:$JAVA_HOME/bin:$GROOVY_HOME/bin export JAVA_HOME PATH GROOVY_PATH
root@darren-virtual-machine:/IDEA/groovy-3.0.3/bin# source /root/.bashrc
root@darren-virtual-machine:/IDEA/groovy-3.0.3/bin# groovy -v
Groovy Version: 3.0.3 JVM: 1.8.0_252 Vendor: Private Build OS: Linux
2.4 使用idea創建一個groovy項目
創建一個class類型的groovy的文件
根據Java語法,寫一個簡單代碼
public class hellogroovy { public static void main(String[] args){ System.out.println("Heelo Groovy"); } }
執行
不用創建類和對象,直接使用groovy輸出
println "hello groovy"
這里雖然使用的是腳本語言編寫的,但是實際自己生成編譯一個文件,最終還是應用程序類型
groovy的的基礎語法
三 groovy變量
3.1 變量的基本類型
groovy變量的類型,基本都是對象類型
創建一個variable的包
在這個包下創建一個groovy script
寫一個變量,查看變量的類型
結果如下,整形在經過groovy處理后,也會變成對象類型
同理
3.2 變量的定義
使用def定義變量
groovy會主動識別變量的類型,弱類型定義,使用強類型轉換,則變量不會動態的轉換,保證數據的正確性
當使用def定義的變量后,在后面可以任意定期其他類型的變量代替
groovy的字符串string定義
常用的定義方式
使用三引號定義有格式的字符串
雙引號丁克可擴展字符串
可擴展的不僅僅是$變量,也可以是其他表達式
string個Gstring的相互轉換
3.3 String方法
普通類型常用參數的方法
1.字符串填充
字符串比較
獲取字符串的內容及其他方法
def str = "groovy HelloWorld" def str2 = "Hello" println str[0] //取出第一個字母 println str[0..2] //取出前三個字母 println str.minus(str2) //減法
println str - str2 //groovy減法 println str.reverse() // 倒序 println str.capitalize() //首字母大寫 println str.isNumber() //判斷是否為數字
結果
四 groovy邏輯控制
4.1 case語句
package variable def x=1.23 def result switch (x){ case 'foo': result = 'found foo' break case 'bar': result = 'found bar' break case [4,5,6,'inlist']: //列表 result = 'list' break case 12..30: //范圍 result = 'range' break case Integer: result = 'Integer' break case BigDecimal: result = 'big decimal' break default: result = 'default' } println result
執行結果
4.2 for循環
對范圍的循環
def sum = 0 for(i in 0..9){ sum += i } println sum
對list的循環
sum = 0 list = [1,2,3,4,5] for (i in list){ sum += i } println sum
對map進行循環
sum = 0 map_vaule = ['num1':1,'num':2,'num3':3] for (i in map_vaule){ sum += i.value } println sum
五 groovy閉包
5.1 基本使用
package variable def clouser = {println 'Hello Groovy'} clouser.call() //call調用 clouser() //直接調用,類似於一個方法
5.2 閉包調用參數
package variable import org.stringtemplate.v4.ST def clouser = { String name -> println "Hello ${name}"} clouser.call('world') clouser('groovy') def name = "Groovy" clouser(name) println "*****************************************************************" //多個參數 def clouser_1 = { String name_1,age -> println "Hello ${name_1},My age is ${age}"} def name_1 = "John" clouser_1(name_1,4) println "*****************************************************************" // 默認參數it def clouser_2 = { println "Hello ${it}"} def name_3 = "joy" clouser_2(name) println "*****************************************************************" //閉包返回值 def clouser_3 = {String name_4 -> return "Hello $name_4" } def name_4 = "jolly" result = clouser_3(name_4) println result println "*****************************************************************" //沒有return,也會有返回值,返回值為null def clouser_4 = {String name_5 -> println "Hello $name_5" } def name_5 = "wellian" result = clouser_4(name_5) println result
結果如下
5.3 閉包與基本類型使用
package variable import org.stringtemplate.v4.ST println "閉包函數使用" println "*****************通過upto實現階乘**************************" int x = fab(5) println x int fab(int number){ //定義一個閉包函數 int result = 1 //初始值為1 //1調用upto方法,從1到number,做一個1到10的階乘 1.upto(number,{ num -> result *= num}) return result } //通過downto實現階乘 println "*****************通過downto實現階乘**************************" int fab2(int number){ int result = 1 //number.downto(1,{num -> result *= num}) number.downto(1){num -> result *= num} return result } int y = fab2(5) println y //times實現階乘 println "*****************通過times實現求和**************************" int z = cal(101) println z int cal(int number){ int result=0 number.times { num -> result += num //階乘不能使用times方法,因為看源碼,times都是從0開始,不能使用階乘 } return result }
執行結果
閉包函數使用
*****************通過upto實現階乘**************************
120
*****************通過downto實現階乘**************************
120
*****************通過times實現求和**************************
5050
5.4 閉包和String結合的使用
package variable import org.stringtemplate.v4.ST println "閉包函數和字符串結合使用" String str = 'the 2 and 3 is 5' println "each遍歷" str.each { String temp -> print temp //使用println每次換行輸出 } println "\n" println "***********each的返回值是str本身*****************" println str.each{ } println "***********fin方法查找符合條件的第一個****************" println str.find{ String s -> s.isNumber() //第一個數字 } println "***********findAll方法查找符合條件的第一個****************" def list = str.findAll{ String s -> s.isNumber() //所有數字,findall結果是一個集合,可以轉換成列表 } println list.toListString() println "***********any方法查找符合條件,返回的是一個bool值****************" def result = str.any { String s-> s.isNumber() } println result println "***********every方法所有都符合條件,返回的是一個true****************" println str.every { String s -> s.isNumber() } println "***********使用collect方法,遍歷所有內容****************" def list2 = str.collect{ it.toUpperCase() //使用默認參數,同時吧所有的字母轉換為大寫 } println list2.toListString()
結果
閉包函數和字符串結合使用 each遍歷 the 2 and 3 is 5 ***********each的返回值是str本身***************** the 2 and 3 is 5 ***********fin方法查找符合條件的第一個**************** 2 ***********findAll方法查找符合條件的第一個**************** [2, 3, 5] ***********any方法查找符合條件,返回的是一個bool值**************** true ***********every方法所有都符合條件,返回的是一個true**************** false ***********使用collect方法,遍歷所有內容**************** [T, H, E, , 2, , A, N, D, , 3, , I, S, , 5]
5.5 groovy閉包的三個變量,this.owner.delegate
package variable import org.stringtemplate.v4.ST println "閉包函數的三個重要變量,this,owner,delegate" def scriptClouser = { println "scriptClouser this:"+this //代表閉包定義的類 println "scriptClouser owner:"+owner //代表閉包定義處的類或者對象 println "scriptClouser delegate:"+delegate //代表任意對象,默認和owner一致 } scriptClouser.call() //使用call可以明顯知道是調用的閉包 //定義一個內部類 class Person{ def static classClouser = { println "classClouser this:"+this println "classClouser owner:"+owner println "classClouser delegate:"+delegate } def static say(){ def classClouser = { println "methodClassClouser this:"+this println "methodClassClouser owner:"+owner println "methodClassClouser delegate:"+delegate } classClouser.call() } } Person.classClouser.call() Person.say()
執行
package variable import org.stringtemplate.v4.ST println "閉包函數的三個重要變量,this,owner,delegate" def scriptClouser = { println "scriptClouser this:"+this //代表閉包定義的類 println "scriptClouser owner:"+owner //代表閉包定義處的類或者對象 println "scriptClouser delegate:"+delegate //代表任意對象,默認和owner一致 } scriptClouser.call() //使用call可以明顯知道是調用的閉包 //定義一個內部類 class Person{ def static classClouser = { println "classClouser this:"+this println "classClouser owner:"+owner println "classClouser delegate:"+delegate } def static say(){ def classClouser = { println "methodClassClouser this:"+this println "methodClassClouser owner:"+owner println "methodClassClouser delegate:"+delegate } classClouser.call() } } Person.classClouser.call() Person.say()
閉包定義一個閉包
package variable import org.stringtemplate.v4.ST println "閉包函數的三個重要變量,this,owner,delegate" //定義一個內部類 class Person{ def classClouser = { println "classClouser this:"+this println "classClouser owner:"+owner println "classClouser delegate:"+delegate } def say(){ def classClouser = { println "methodClassClouser this:"+this println "methodClassClouser owner:"+owner println "methodClassClouser delegate:"+delegate } classClouser.call() } } Person p = new Person() p.classClouser.call() p.say() //定義閉包內一個閉包 //當在內部類中定義一個閉包,則這三個值一樣的,但是適應閉包的閉包,就不會一致了 def nestClouser = { def innerClouser = { println "innerClouser this:"+this println "innerClouser owner:"+owner println "innerClouser delegate:"+delegate } innerClouser.call() } nestClouser.call()
結果
閉包函數的三個重要變量,this,owner,delegate classClouser this:variable.Person@6e46d9f4 classClouser owner:variable.Person@6e46d9f4 classClouser delegate:variable.Person@6e46d9f4 methodClassClouser this:variable.Person@6e46d9f4 methodClassClouser owner:variable.Person@6e46d9f4 methodClassClouser delegate:variable.Person@6e46d9f4 innerClouser this:variable.closestudy@644c78d4 innerClouser owner:variable.closestudy$_run_closure1@532a02d9 innerClouser delegate:variable.closestudy$_run_closure1@532a02d9
修改默認的delegate
package variable import org.stringtemplate.v4.ST println "閉包函數的三個重要變量,this,owner,delegate" //定義一個內部類 class Person{ def classClouser = { println "classClouser this:"+this println "classClouser owner:"+owner println "classClouser delegate:"+delegate } def say(){ def classClouser = { println "methodClassClouser this:"+this println "methodClassClouser owner:"+owner println "methodClassClouser delegate:"+delegate } classClouser.call() } } Person p = new Person() //p.classClouser.call() //p.say() //定義閉包內一個閉包 //當在內部類中定義一個閉包,則這三個值一樣的,但是適應閉包的閉包,就不會一致了 def nestClouser = { def innerClouser = { println "innerClouser this:"+this println "innerClouser owner:"+owner println "innerClouser delegate:"+delegate } innerClouser.delegate = p //修改默認的delegate對象 innerClouser.call() } nestClouser.call()
執行結果
閉包函數的三個重要變量,this,owner,delegate innerClouser this:variable.closestudy@4a8ab068 innerClouser owner:variable.closestudy$_run_closure1@611f8234 innerClouser delegate:variable.Person@7bb3a9fe
- 大多數情況下,this owner delegate的值是一樣的
- 當使用閉包的閉包,owner delegate就和this不一樣了
- 當人為修改delegate對象,這三個就完全不一樣(this和owner不能修改)
5.6 閉包函數的委托策略
package variable import org.stringtemplate.v4.ST println "閉包函數的委托策略" class Student{ String name def pretty= { "My name is ${name}" } String toSting(){ pretty.call() } } class Teacher{ String name } def stu = new Student(name:'natasha') def tea = new Teacher(name: 'John') println stu.toSting() //結果是My name is natasha //修改delegate的默認對象 stu.pretty.delegate = tea //使用委托策略,當Deletgate沒有值,就會繼續從student中尋找,比如修改String name1 和def tea = new Teacher(name1: 'John'),輸出的值依然是natasha,這時如果委托策略修改為Clouser.DELEGATE_ONLY,代碼就會報錯 stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST println stu.toSting()
執行
閉包函數的委托策略
My name is natasha
My name is John
參考:https://www.bilibili.com/video/BV1nt411b7dE?p=13