// 1. 能夠和Java同樣
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello Groovy")
}
}
// 2. 直接輸出(兩種)
println "Hello Groovy"
println("Hello Groovy")
複製代碼
變量的類型:基本類型(java中的int/float/double/byte/char/long/short)和對象類型(String等) ,在Groovy中最終都是對象類型。java
int x = 10
println x.class //結果爲:class java.lang.Integer
double y = 3.14
println y.class //結果爲:class java.lang.Double
複製代碼
因而可知,Groovy中的基本類型最終會被編譯器包裝成對象類型python
變量的定義:強類型定義方式和弱類型def定義方式android
def x1 = 10
def y1 = 3.14
def str1 = 'groovy str'
x1 = 'grovvy def'
println x1.class //class java.lang.Integer
println y1.class //class java.math.BigDecimal
println str1.class //class java.lang.String
println x1.class //class java.lang.String
複製代碼
強類型定義及定義的時候寫明變量的類型,而def則由編譯器自行推導變量的類型編程
強類型定義方式和弱類型def定義方式的選擇:json
* 變量用於本類或者本模塊而不會用於其它類或者其餘模塊,推薦使用def類型,這樣能夠隨時動態的轉換爲其它類型;
* 變量要用於其它類或是其它模塊,強烈建議使用強類型定義方式。使用強類型定義的方式不能動態轉換類型,才能使外界傳入或者調用的時候不會對於數據的類型產生疑惑,這樣就保證外界傳入的數據必定是咱們想要的正確的類型的數據。
複製代碼
//1. 單引號定義的就是java中的String,內容即爲''內的字符串,而且不可更改
def str1 = 'a single string'
println str1.class //class java.lang.String
// 有特殊字符一樣的經過反斜槓轉義
def str2 = 'a single \'special\' string'
//2. 三個單引號定義的是有格式的字符串,會直接按照咱們寫的格式進行輸出,而不用像Java中進行拼接
def trebleStr = '''line one line two line three '''
//3. 雙引號
def name = "Groovy"
println name.class //class java.lang.String
// 字符串模板
def sayHello = "Hello $name"
// 字符串模板也能夠是表達式
def sum = "the sum of 2 and 3 equals ${2 + 3}"
複製代碼
//字符串填充:
// 1. center(Number numberOfChars,CharSequence padding) ,將字符串做爲中心進行填充
// 當numberOfChars小於或等於str自己的長度時,不進行填充操做,大於則用pandding擴展至長度numberOfChars,從字符串的右邊(尾)進行填充,再到左邊(頭)
def str = "groovy"
println str.center(8) //結果: groovy ,不傳padding表明以空格填充
println str.center(5,"a") //結果: groovy
println str.center(6,"a") //結果:groovy
println str.center(7,"a") //結果:groovya
println str.center(8,"a") //結果:agroovya
println str.center(9,"a") //結果:agroovyaa
// 2. padLeft(Number numberOfChars,CharSequence padding) ,在字符串的左邊進行填充
// 3. padRight(Number numberOfChars,CharSequence padding),在字符串的右邊進行填充
//字符串比較:
def string = "groovy"
def string1 = "Groovy"
println string.compareTo(string1) // 32 結果大於0,str大於Str2
println string.compareToIgnoreCase(string1) // 0 結果等於0,str等於忽略大小寫的Str
println string1.compareTo(str) // -32 結果小於0,str2小於str
println string > string1 // true 可用操做符直接進行比較
println string == string1.toLowerCase() // true
//獲取字符串中的字符:
def string2 = "groovy"
println string2.getAt(0) // g
println string2.getAt(0..1) // gr
println string2[0] // g
println string2[0..1] // gr
//字符串中的減法(取差集):
def string3 = "groovy"
def string4 = "hello"
def string5 = "hello groovy"
def string6 = "groovy hello "
println string3.minus(string4) // groovy, str中沒有包含str2
println string3.minus(string5) // groovy, str中沒有包含str3
println string5.minus(string4) // groovy, str3中包含了str2 (注意結果包含了空格)
println string5.minus(string6) // hello groovy, str3z中沒有包含str4
println string5 - string3 // hello, str3z中包含了str(注意結果包含了空格)
// 其它方法
def string7 = "hello groovy"
println string7.reverse() // yvoorg olleh,字符串反轉
println string7.capitalize()// Hello groovy,首字母大寫
println string7.isNumber() // false,是否全是數字
def string8 = "1234"
println string8.toInteger() // 1234
println string8.toBigDecimal() // 1234
println string8.toDouble() // 1234.0
複製代碼
String judgeType(Object x) {
def result
switch (x) {
case "string":
result = "x is string"
break
case [4, 5, 6, 7,'inList']: //列表(數據結構中講解)
result = "x is in list [4, 5, 6, 7,'inList']"
break
case 10..15: //範圍range(數據結構中講解)
result = "x is in range 10..15"
break
case Integer:
result = "x is Integer"
break
case BigDecimal:
result = "x is BigDecimal"
break
case List:
result = "x is List"
break
default:
result = "no match"
break
}
return result
}
複製代碼
// 1. 範圍中的for循環
def sum = 0
for (i in 0..9) {
sum += i
}
println sum // 45
sum = 0
// 2. list中的for循環
for (i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) {
sum += i
}
println sum // 45
// 3. map中的for循環
for (i in ['java': 1, ' groovy': 2, 'python': 3]) {
println "key:${i.key} value:${i.value}"
}
複製代碼
定義:Groovy中的閉包是一個開放的,匿名的代碼塊,能夠接受參數,能夠返回值而且能夠賦值給閉包變量。閉包能夠引用在其周圍範圍內聲明的變量,與閉包的正式定義相反,Groovy語言中的Closure也能夠包含在其周圍範圍以外定義的自由變量。api
語法:{ [closureParameters -> ] statements } 。其中[closureParameters->]是一個以逗號分隔的可選參數列表,並且statements 有0條或更多條Groovy語句,參數看起來相似於方法參數列表,這些參數能夠是類型化的或非類型化的。指定參數列表時, - >字符是必需的,用於將參數列表與Groovy語句分開。數組
代碼示例bash
{ item++ } //一個引用名爲item的變量的閉包
{ -> item++ } //經過添加箭頭( - >)能夠明確地將閉包參數與代碼分開
{ println it } //使用隱式參數(it)的閉包
{ it -> println it } //上面的一個替代版本,它是一個顯式參數
{ name -> println name } //在這種狀況下,一般最好爲參數使用顯式名稱
{ String x, int y -> //一個閉包接受兩個類型參數
println "hey ${x} the value is ${y}"
}
{ reader -> //閉包能夠包含多個語句
def line = reader.readLine()
line.trim()
}
// 上面代碼定義一個名爲 closure_name 的閉包,用途由 closure body 中的代碼定義。
// 匿名閉包指不聲明閉包變量名,只有閉包方法體{ //closure body }
def closure_name = {
// closure body
}
複製代碼
閉包類:一個閉包是groovy.lang.Closure類的一個實例,它能夠像任何其餘變量同樣賦值給變量或字段,儘管它是一個代碼塊。Java8中lambda表達式也引入了閉包概念,類com.sun.corba.se.spi.orbutil.closure.Closure。Groovy將閉包定義爲Closure類的實例,與Java 8中的lambda表達式大相徑庭。數據結構
參數閉包
閉包調用:def closure_name = { // closure body }
閉包使用:閉包能夠用做方法的參數。在Groovy中,不少用於數據類型(例如列表和集合)的內置方法都有閉包做爲參數類型。
def clos = { param -> println "${str1} ${param}" }
clos("Groovy")
clos.call("World");
// 閉包和列表
def lst = [11, 12, 13, 14];
lst.each {println it}
// 閉包和映射
def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"]
mp.each {println it}
mp.each {println "${it.key} maps to: ${it.value}"}
複製代碼
閉包進階
// '注:此段代碼位於HelloWorld.groovy文件中'
// '1. 直接在閉包中使用時: 三者沒有區別'
def scriptClosure = {
println "scriptClosure this:" + this // 表明閉包定義處的類
println "scriptClosure owner:" + owner // 表明閉包定義處的類或對象(靜態是class文件,非靜態是對象)
println "scriptClosure delegate:" + delegate // 表明任意對象,默認與owner一致
}
// 輸出結果:
scriptClosure this:main.HelloWorld@6ce139a4
scriptClosure owner:main.HelloWorld@6ce139a4
scriptClosure delegate:main.HelloWorld@6ce139a4
// '2. 閉包內部的閉包,this與 owner和delegate是不一樣的'
/**
* 1. 在類或者閉包中定義的閉包,三者沒有區別
* 2. 在閉包中定義的閉包 this 與 owner ,delegate就不同了
* 3. this :永遠會指向最外層的類
* 4. owner和delegate默認都會指向定義出最近的closure對象
*/
def nestClosure = {
def innerClosure = {
println "innerClosure this:" + this
println "innerClosure owner:" + owner
println "innerClosure delegate:" + delegate
}
innerClosure.call()
}
nestClosure.call()
// 輸出結果:
innerClosure this:main.HelloWorld@6ce139a4
innerClosure owner:main.HelloWorld$_run_closure6@33afa13b
innerClosure delegate:main.HelloWorld$_run_closure6@33afa13b
// '3. 修改delegate指向的對象'
def nestClosure = {
def innerClosure = {
println "innerClosure this:" + this
println "innerClosure owner:" + owner
println "innerClosure delegate:" + delegate
}
innerClosure.delegate = new HelloWorld()
innerClosure.call()
}
nestClosure.call()
// 輸出結果:
innerClosure this:main.HelloWorld@6ce139a4
innerClosure owner:main.HelloWorld$_run_closure6@45b9a632
innerClosure delegate:main.HelloWorld@25d250c6
複製代碼
// '1. 正常調用'
class Student {
String name
def pretty = { println "My name is ${name}" }
String toString() {
pretty.call()
}
}
class Teather {
String name
}
def student = new Student(name: "groovy")
def teather = new Teather(name: "android")
student.toString()
// 結果:My name is groovy
// 緣由:每一個閉包都會有本身的委託策略,默認的委託策略是 Closure.OWNER_FIRST(所以這也是爲何大多數狀況和owner一致的緣由)
// 2. '更改委託策略委託'
student.pretty.delegate = teather
// 更改對應的委託策略委託才真正生效
student.pretty.resolveStrategy = Closure.DELEGATE_FIRST
student.toString()
// 結果:My name is android
複製代碼
閉包代碼塊中,只要是this、owner、delegate三者中擁有的屬性和方法,閉包中都是能夠直接(可省略引用)調用到的。區別在於存在一個執行順序,執行順序是閉包的委託策略決定。
// rootProject : build.gradle
buildscript { ScriptHandler scriptHandler ->
// 配置工程倉庫地址
scriptHandler.repositories { RepositoryHandler repositoryHandler ->
repositoryHandler.jcenter()
repositoryHandler.mavenCentral()
repositoryHandler.mavenLocal()
repositoryHandler.ivy {}
repositoryHandler.maven { MavenArtifactRepository mavenArtifactRepository ->
mavenArtifactRepository.name 'personal'
mavenArtifactRepository.url 'http://localhost:8081/nexus/repositories/'
mavenArtifactRepository.credentials {
username = 'admin'
password = 'admin123'
}
}
}
}
// ======================== 上述簡化後 =============================
buildscript {
/**
* 配置工程倉庫地址
* 因爲repositories這個閉包中的delegate是repositoryHandler,
* 所以能夠省略repositoryHandler的引用,直接使用其屬性和方法。
*/
repositories {
jcenter()
mavenCentral()
mavenLocal()
ivy {}
maven {
name 'personal'
url 'http://localhost:8081/nexus/repositories/'
credentials {
username = 'admin'
password = 'admin123'
}
}
}
}
複製代碼
1..10 - 包含範圍的示例
1 .. <10 - 獨佔範圍的示例
'a'..'x' - 範圍也能夠由字符組成
10..1 - 範圍也能夠按降序排列
'x'..'a' - 範圍也能夠由字符組成並按降序排列。
def range = 1..10
複製代碼
contains() 檢查範圍是否包含特定值
get() 返回此範圍中指定位置處的元素。
getFrom() 得到此範圍的下限值。
getTo() 得到此範圍的上限值。
isReverse() 這是一個反向的範圍,反向迭代
size() 返回此範圍的元素數。
subList() 返回此指定的fromIndex(包括)和toIndex(排除)之間的此範圍部分的視圖
複製代碼
[11,12,13,14] - 整數值列表
['Angular','Groovy','Java'] - 字符串列表
[1,2,[3,4],5] - 嵌套列表
['Groovy',21,2.11] - 異構的對象引用列表
[] - 一個空列表
def arrayList = [1, 2, 3, 4]
複製代碼
add() 將新值附加到此列表的末尾。
contains() 若是此列表包含指定的值,則返回true。
get() 返回此列表中指定位置的元素。
isEmpty() 若是此列表不包含元素,則返回true
minus() 建立一個由原始元素組成的新列表,而不是集合中指定的元素。
plus() 建立由原始元素和集合中指定的元素組成的新列表。
pop() 今後列表中刪除最後一個項目
remove() 刪除此列表中指定位置的元素。
reverse() 建立與原始列表的元素相反的新列表
size() 獲取此列表中的元素數。
sort() 返回原始列表的排序副本。
複製代碼
['TopicName':'Lists','TopicName':'Maps'] - 具備TopicName做爲鍵的鍵值對的集合及其相應的值。
[:] - 空映射。
def map = ['key': 'value']
複製代碼
containsKey() 此映射是否包含此鍵?
get() 查找此Map中的鍵並返回相應的值。若是此映射中沒有鍵的條目,則返回null。
keySet() 獲取此映射中的一組鍵。
put() 將指定的值與此映射中的指定鍵相關聯。若是此映射先前包含此鍵的映射,則舊值將替換爲指定的值。
size() 返回此地圖中的鍵值映射的數量。
values() 返回此地圖中包含的值的集合視圖。
複製代碼
class HelloGroovy {
String name
Integer age
// def等同於Java中的Object
def invokeMethod(String method, Object args){
return "invokeMethod : the method is ${method},the args is ${args}"
}
static void main(String[] args) {
//賦值: 能夠不初始化,也能夠初始化部分或者所有
def hello = new HelloGroovy(name: "dog",age: 2)
//hello.name的方式獲取變量的值,其實最終的實現也是 animal.getName()
println "this animal's name is ${hello.name},the animal's age is ${hello.age}"
}
}
複製代碼
class HelloGroovy {
/**
* 一個方法在找不到時,調用這個方法做爲代替
* 優先於 invokeMethod()
*/
def methodMissing(String method, Object args) {
return "methodMissing : the method is ${method},the args is ${args}"
}
// 一個方法在找不到時,調用這個方法做爲代替
def invokeMethod(String method,Object args){
return "invokeMethod : the method is ${method},the args is ${args}"
}
static void main(String[] args) {
def hello = new HelloGroovy()
//調用不存在的方法
hello.call()
}
}
複製代碼
class HelloGroovy {
String name
Integer version
static void main(String[] args) {
// 元編程爲類動態注入屬性
HelloGroovy.metaClass.desc = "我是描述信息"
def groovy = new HelloGroovy()
groovy.desc = "我是Groovy"
println(groovy.desc)
// 元編程爲類動態注入方法
HelloGroovy.metaClass.descUpcase = {
it -> it.toUpperCase()
}
HelloGroovy.metaClass.english = "I am Groovy"
def helloGroovy = new HelloGroovy()
println helloGroovy.descUpcase(helloGroovy.english)
// 元編程爲類動態注入靜態方法
HelloGroovy.metaClass.static.addVersion = {
it -> it + 1
}
HelloGroovy.metaClass.desc = "注入靜態方法"
def staticInject = new HelloGroovy(name: "groovy", version: 2)
println "the language's name is ${staticInject.name}, the language's next version is ${staticInject.addVersion(staticInject.version)}"
}
}
// 輸出結果:
我是Groovy
I AM GROOVY
the language's name is groovy, the language's next version is 3
複製代碼
//Json解析:JSON文本或閱讀器內容解析爲Groovy數據結構的類
def jsonSlurper = new JsonSlurper()
// 文本解析
def object = jsonSlurper.parseText('{ "name": "John", "ID" : "1"}')
println(object.name);
println(object.ID);
// 解析整數列表
Object listObj = jsonSlurper.parseText('{ "List": [2, 3, 4, 5] }')
listObj.each { println it }
// 解析基本數據類型列表
def obj = jsonSlurper.parseText ''' {"Integer": 12, "fraction": 12.55, "double": 12e13}'''
println(obj.Integer);
println(obj.fraction);
println(obj.double);
//Json序列化:將Groovy對象序列化爲JSON字符串
def output = JsonOutput.toJson([name: 'John', ID: 1])
println(output)
class Student{
String name
Integer ID
}
def output1 = JsonOutput.toJson([new Student(name: 'John',ID:1), new Student(name: 'Mark',ID:2)])
println(output1);
複製代碼
//XML解析
def stringXml = ''' <collection shelf = "New Arrivals"> <movie title = "Enemy Behind"> <type>War, Thriller</type> <format>DVD</format> <year>2003</year> <rating>PG</rating> <stars>10</stars> <description>Talk about a US-Japan war</description> </movie> <movie title = "Transformers"> <type>Anime, Science Fiction</type> <format>DVD</format> <year>1989</year> <rating>R</rating> <stars>8</stars> <description>A schientific fiction</description> </movie> <movie title = "Ishtar"> <type>Comedy</type> <format>VHS</format> <year>1987</year> <rating>PG</rating> <stars>2</stars> <description>Viewable boredom </description> </movie> </collection> '''
def parser = new XmlParser()
// 解析文本
def text = parser.parseText(stringXml)
println text.movie[0].type[0].text()
// 解析文件
def doc = parser.parse("E:\\CodeProject\\groovy\\HelloWorld\\src\\main\\Movies.xml")
println doc
// 輸出結果:
War, Thriller
collection[attributes={shelf=New Arrivals}; value=[movie[attributes={title=Enemy Behind}; value=[type[attributes={}; value=[War, Thriller]], format[attributes={}; value=[DVD]], year[attributes={}; value=[2003]], rating[attributes={}; value=[PG]], stars[attributes={}; value=[10]], description[attributes={}; value=[Talk about a US-Japan war]]]], movie[attributes={title=Transformers}; value=[type[attributes={}; value=[Anime, Science Fiction]], format[attributes={}; value=[DVD]], year[attributes={}; value=[1989]], rating[attributes={}; value=[R]], stars[attributes={}; value=[8]], description[attributes={}; value=[A schientific fiction]]]], movie[attributes={title=Ishtar}; value=[type[attributes={}; value=[Comedy]], format[attributes={}; value=[VHS]], year[attributes={}; value=[1987]], rating[attributes={}; value=[PG]], stars[attributes={}; value=[2]], description[attributes={}; value=[Viewable boredom]]]]]]
// 解析節點遍歷
doc.movie.each{
bk->
print("Movie Name:")
println "${bk['@title']}"
print("Movie Type:")
println "${bk.type[0].text()}"
print("Movie Format:")
println "${bk.format[0].text()}"
print("Movie year:")
println "${bk.year[0].text()}"
print("Movie rating:")
println "${bk.rating[0].text()}"
print("Movie stars:")
println "${bk.stars[0].text()}"
print("Movie description:")
println "${bk.description[0].text()}"
println("*******************************")
}
//XML標記生成器
def mB = new MarkupBuilder()
// 根節點是誰,調用的方法就是誰
mB.collection(shelf : 'New Arrivals') {
movie(title : 'Enemy Behind')
type('War, Thriller')
format('DVD')
year('2003')
rating('PG')
stars(10)
description('Talk about a US-Japan war')
}
// 注1:mB.collection() -這是一個標記生成器,用於建立<collection> </ collection>的頭XML標籤
// 注2:movie(title : 'Enemy Behind') -這些僞方法使用此方法建立帶有值的標記的子標記。經過指定一個名爲title的值,這實際上表示須要爲該元素建立一個屬性。
// 注3:向僞方法提供閉包以建立XML文檔的剩餘元素。
// 根據map生成XML
def mapXml = [1 : ['Enemy Behind', 'War, Thriller','DVD','2003',
'PG', '10','Talk about a US-Japan war'],
2 : ['Transformers','Anime, Science Fiction','DVD','1989',
'R', '8','A scientific fiction'],
3 : ['Trigun','Anime, Action','DVD','1986',
'PG', '10','Vash the Stam pede'],
4 : ['Ishtar','Comedy','VHS','1987', 'PG',
'2','Viewable boredom ']]
// Compose the builder
def MOVIEDB = mB.collection('shelf': 'New Arrivals') {
mapXml.each {
sd ->
mB.movie('title': sd.value[0]) {
type(sd.value[1])
format(sd.value[2])
year(sd.value[3])
rating(sd.value[4])
stars(sd.value[4])
description(sd.value[5])
}
}
}
println MOVIEDB
複製代碼
// 讀取文件
def file = new File('src/main/Movies.xml')
file.eachLine {
line -> println "line : $line";
}
// 讀取文件的內容到字符串
println file.text
// 讀取文件部份內容
def reader = file.withReader {
char[] buff = new char[100]
it.read(buff)
return buff
}
println reader
// 寫入文件
new File('E:\\CodeProject\\groovy\\HelloWorld','Example.txt').withWriter('utf-8') {
writer -> writer.writeLine 'Hello World'
}
// 獲取文件的大小
println file.length()
// 測試文件是不是目錄
println "File? ${file.isFile()}"
println "Directory? ${file.isDirectory()}"
// 建立目錄
def fileMkDir = new File('E:\\CodeProject\\groovy\\HelloWorld\\IO')
fileMkDir.mkdir()
// 刪除文件
fileMkDir.delete()
// 複製文件
def src = new File("E:\\CodeProject\\groovy\\HelloWorld\\Example.txt")
def dst = new File("E:\\CodeProject\\groovy\\HelloWorld\\Example1.txt")
dst << src.text
// 獲取目錄內容
def rootFiles = file.listRoots()
rootFiles.each {
println it.absolutePath
}
// 對象存儲,寫入文件
def saveObject(Object o, String path) {
//判斷目標文件不存在,建立文件
File destFile = new File(path)
try {
if (!destFile.exists()) {
destFile.createNewFile()
}
} catch (Exception e) {
e.printStackTrace()
}
if (o == null) {
return
}
try {
destFile.withObjectOutputStream { outputStream ->
outputStream.writeObject(o)
}
} catch (Exception e) {
e.printStackTrace()
}
}
// 拷貝文件
def copy(String sourcePath, String destationPath) {
//判斷目標文件不存在,建立文件
File destFile = new File(destationPath)
try {
if (!destFile.exists()) {
destFile.createNewFile()
}
} catch (Exception e) {
e.printStackTrace()
}
File sourceFile = new File(sourcePath)
try {
if (!sourceFile.exists()) {
return
}
} catch (Exception e) {
e.printStackTrace()
return
}
def lines = sourceFile.readLines()
destFile.withWriter {writer->
lines.each {line->
writer.append(line).append('\r\n')
}
}
}
複製代碼
注:如有什麼地方闡述有誤,敬請指正。期待您的點贊哦!!!