Groovy是增强Java平台的唯一的脚本语言。它提供类似于Java的语法,内置映射(Map)、列表(List)、方法、类、闭包(closure)以及生成器。
Groovy是动态弱类型语言,即Groovy不要求声明变量的类型、方法的参数或者方法的返回值。这意味着在不同环境下,变量可以以多种方式使用。
Groovy类和Java是二进制兼容的。这意味着Groovy编译器产生的字节码与Java编译器产生的字节码是完全一样的。因此,对JVM而言,Groovy和Java是完全一样的。
Groovy是一门面向对象的语言。
数值和表达式
两个整数的除法运算通常会产生一个浮点数,即使其结果可能是一个整数。
如表达式6/3的结果是浮点数2.0,而不是整数2.
为了获得两个整型值相除的整数部分,必须调用intdiv方法:
13.intdiv(5)
该表达式的结果是整数2.
使用取模运算符(%)可以得到两个整数操作数相除的余数。但是对一个浮点数求模,或者对一个含有浮点数参数的整数求模都是非法的。
在Groovy中,第一次使用某个变量时,需要使用def关键字来声明变量。
变量的命名规则:可以由字母、数字和下划线组成,对大小写敏感,首字符必须是字母。
字符串和正则表达式
在Groovy中,可以使用单引号('abc')、双引号("abc")、或者三引号('''abc''')来封装字符串。使用三引号表示的字符串可以包含多行文本。
使用单引号封装的字符串的值就是所列出的字符序列本身。而在双引号和三引号中,任何包含在解释型字符串中的${expression}都将被求值,
其结果是字符串的一部分。如:
def age = 25
'My age is ${age}' //My age is ${age}
"My age is ${age}" //My age is 25
'''My age is ${age}''' //My age is 25
"My age is \${age}" //My age is ${age}
Groovy是动态弱类型语言,即Groovy不要求声明变量的类型、方法的参数或者方法的返回值。这意味着在不同环境下,变量可以以多种方式使用。
Groovy类和Java是二进制兼容的。这意味着Groovy编译器产生的字节码与Java编译器产生的字节码是完全一样的。因此,对JVM而言,Groovy和Java是完全一样的。
Groovy是一门面向对象的语言。
数值和表达式
两个整数的除法运算通常会产生一个浮点数,即使其结果可能是一个整数。
如表达式6/3的结果是浮点数2.0,而不是整数2.
为了获得两个整型值相除的整数部分,必须调用intdiv方法:
13.intdiv(5)
该表达式的结果是整数2.
使用取模运算符(%)可以得到两个整数操作数相除的余数。但是对一个浮点数求模,或者对一个含有浮点数参数的整数求模都是非法的。
在Groovy中,第一次使用某个变量时,需要使用def关键字来声明变量。
变量的命名规则:可以由字母、数字和下划线组成,对大小写敏感,首字符必须是字母。
字符串和正则表达式
在Groovy中,可以使用单引号('abc')、双引号("abc")、或者三引号('''abc''')来封装字符串。使用三引号表示的字符串可以包含多行文本。
使用单引号封装的字符串的值就是所列出的字符序列本身。而在双引号和三引号中,任何包含在解释型字符串中的${expression}都将被求值,
其结果是字符串的一部分。如:
def age = 25
'My age is ${age}' //My age is ${age}
"My age is ${age}" //My age is 25
'''My age is ${age}''' //My age is 25
"My age is \${age}" //My age is ${age}
通用的原则是,只在字符串需要被解释的时候使用双引号,在其他情况下字符串使用单引号。
闭包常用方法demo,直接贴代码demo.groovy,运行时直接输入groovy demo.groovy:
// groovy中的闭包及常用方法 // 闭包的两种写法: // 1. 有参数的闭包:def clos = {参数名 -> 代码块} // 2. 无参数的闭包:def clos = {代码块} /****************************************************/ def hello = 'Hello' def clos = { param -> println "${hello},${param}" } def clos2 = { p1,p2 -> println "the parameters are ${p1} and ${p2}" } def demo(clo) { clo('zyf') } // 闭包的调用方式 clos.call("zyf") clos('zyf') clos'zyf' clos2(1,2) // 也可以写成:clos2 1,2 // 参数有闭包的方法的调用方式 demo(clos) demo clos demo{ param -> println "hello,${param}" } /********输出结果********/ //Hello,zyf //Hello,zyf //the parameters are 1 and 2 //Hello,zyf //hello,zyf /********输出结果********/ /****************************************************/ // upto方法无参数时表示循环几次(如:从1循环到3),有参数时,参数从几递增到几(如:从3递增到4) 1.upto(3) { println "abc" } def count = 0 3.upto(4) { p -> count += p } println "count: ${count}" /********输出结果********/ //abc //abc //abc //count: 7 /********输出结果********/ /****************************************************/ // each方法常常用于列表、映射和字符串,以遍历每个元素,并将闭包应用于每个元素 [1,2].each { println it } ['zhangsan' : 21,'lisi' : 22].each { println it } ['zhangsan' : 21,'lisi' : 22].each { println "${it.key} maps to : ${it.value}" } ['zhangsan' : 21,'lisi' : 23].each { p -> if (p.value > 22) { println "${p.key} value over 22" } else { println "${p.key} value low 23" } } /********输出结果********/ //1 //2 //zhangsan=21 //lisi=22 //zhangsan maps to 21 //lisi maps to 22 //zhangsan value low 23 //lisi value over 22 /********输出结果********/ /****************************************************/ // find方法返回集合中符合某个判断标准的第一个值,若不存在则符合null。在闭包中,集合元素使用的判断条件必须是布尔表达式。 def f = [1,2].find { it -> it > 1 } println "find : ${f}" /********输出结果********/ //find 2 /********输出结果********/ /****************************************************/ // findAll方法将遍历所有元素,并返回一个符合条件的列表。 def fa = ['zhangsan' : 21,'lisi' : 23,wangwu : 24].findAll {// map的key默认都是字符串,故可以不用单引号或双引号 it -> it.value > 22 } println "find all : ${fa}" fa.each { println it } [1,2,3].findAll { it -> it > 1 }.each { println it } /********输出结果********/ //find all [lisi:23,wangwu:24] //lisi=23 //wangwu=24 //2 //3 /********输出结果********/ /****************************************************/ // any方法将遍历检查集合的每个元素,以确认:对至少一个元素来说,由闭包提供的布尔断言是否合法。 def a = [1,2].any { it -> it > 1 } println "any one over 1? ${a}" /********输出结果********/ //any one over 1? true /********输出结果********/ /****************************************************/ // every方法则用来检查:对集合的所有元素来首,闭包提供的布尔断言是否合法。 def e = [1,2].every { it -> it >1 } println "every one over 1? ${e}" /********输出结果********/ //every one over 1? false /********输出结果********/ /****************************************************/ // collect方法将遍历某个集合,并使用闭包中的变换方法将集合中的每个元素转换为一个新值。返回一个由转换后的值所组成的列表。 def list = [1,3,4].collect { it -> return it * it } println "list: ${list}" list = (0..2).collect {// ..表示范围,从start到end的值,这里表示(0,1,2) it -> 2 * it } println "list:${list}" list = (0..<2).collect {// ..<也表示范围,但是不包含右边界值,这里表示(0,1) it -> 3 * it } println "list:${list}" def s = ['zhangsan' : 21,'lisi' : 22] list = s.collect { it -> ++it.value } def olderS = s.collect { it -> ++it.value return it } println "s : ${s}" println "list : ${list}" println "olderS : ${olderS}" /********输出结果********/ //list: [1,4,9,16] //list:[0,4] //list:[0,3] //s : [zhangsan:23,lisi:24] //list : [22,23] //olderS : [zhangsan=23,lisi=24] /********输出结果********/ /****************************************************/ // inject方法可用于遍历集合,首先将需要传递的初始值和集合项目传递给闭包,此时其传递的初始值将作为初始结果, // 然后再和下一个集合元素一起传给闭包,以此类推。 def factorial = [2,4].inject(1) { prevIoUs,element -> println "pre: ${prevIoUs},ele: ${element}" prevIoUs * element // 这里的prevIoUs分别是上次计算的结果值1,6;element分别是集合元素2,4 } println "Factorial(4) : ${factorial}" /********输出结果********/ //pre: 1,ele: 2 //pre: 2,ele: 3 //pre: 6,ele: 4 //Factorial(4) : 24 /********输出结果********/ /****************************************************/ // 闭包作为返回值 def multiply(x) { return { y -> return x * y } } def twice = multiply(2) println "twice(3) = ${twice(3)}" // 这里的twice(3)相当于multiply(2)(3),后面的3是传递给作为返回值的闭包的参数 /********输出结果********/ //twice(3) = 6 /********输出结果********/ /****************************************************/ // 冒泡排序 def swap = { sList,p,q -> def temp = sList[p] sList[p] = sList[q] sList[q] = temp } def minPosition = { pList,from -> def mPos = from def nextFrom = from + 1 for (i in nextFrom..<pList.size()) { if (pList[i] < pList[mPos]) { mPos = i } } return mPos } def selectionSort = { l -> def size = l.size() - 1 for (j in 0..<size) { def minPos = minPosition(l,j) swap(l,minPos,j) } return l } def table = [2,3] def sorted = selectionSort(table) println "sorted : ${sorted}" /********输出结果********/ //sorted : [1,4] /********输出结果********/ /****************************************************/ /****************************************************/ // 文件操作 println "str's length:" + "a c d d".tokenize().size() // tokenize切分词返回列表,如[a,c,d,d] /********输出结果********/ //str's length:4 /********输出结果********/ /****************************************************/ // File类提供了eachFile方法,用来表示某个目录的文件对象,它接收闭包作为其参数,且对该目录中每个文件调用此闭包 def listDir(dirFile,indent) { dirFile.eachFile { file -> (0..<indent).each { print " " } println "${file.getName()}" if (file.isDirectory()) { listDir(file,indent + 2) } } } def printDir(dirName) { listDir(new File(dirName),0) } // 命令行调用时,参数跟在文件名后,如:groovy demo.groovy c:\Users\...\Desktop /* if (args.size() != 1 || new File(args[0]).isDirectory() == false) { println "please enter a directory" } else { printDir(args[0]) } */ /****************************************************/ // File类提供了eachFileRecurse方法,它可以遍历某个目录中的所有文件,并且递归遍历子目录 def printDir2(dirName,size) { new File(dirName).eachFileRecurse { file -> if (file.getName().size() > size) // 遍历查找文件名大于给定长度的文件 println "the file ${file.getName()} name's size over ${size}" } } /* if (args.size() != 2 || new File(args[0]).isDirectory() == false) println "please enter 2 right args!" else printDir2(args[0],args[1].toInteger()) */ /****************************************************/ // xml解析 // 文件library.xml的内容: //<library> // <book> // <title id='111'>java</title> // </book> // <book> // <title id='222'>c</title> // </book> //</library> def doc = new XmlParser().parse('library.xml') println "${doc.book[0].title.text()}" doc.book.each { // 遍历每一个book节点 it -> println "${it.title.text()}" } doc.book.title.each { // 遍历每一个book节点的每一个title节点 it -> println "${it.text()}" } println doc.book.title[0]['@id'] println doc.book.title['@id'] /********输出结果********/ //java //java //c //java //c //111 //[111,222] /********输出结果********/