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
- //Hello, zyf
- //the parameters are 1 and 2
- //Hello, zyf
- //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, 2, 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, 2, 4]
- //list:[0, 3]
- //s : [zhangsan:23, lisi:24]
- //list : [22, 23]
- //olderS : [zhangsan=23, lisi=24]
- /********输出结果********/
- /****************************************************/
- // inject方法可用于遍历集合,首先将需要传递的初始值和集合项目传递给闭包,此时其传递的初始值将作为初始结果,
- // 然后再和下一个集合元素一起传给闭包,以此类推。
- def factorial = [2, 3, 4].inject(1) {
- previous, element ->
- println "pre: ${previous}, ele: ${element}"
- previous * element // 这里的previous分别是上次计算的结果值1,2,6;element分别是集合元素2,3,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, 4, 1, 3]
- def sorted = selectionSort(table)
- println "sorted : ${sorted}"
- /********输出结果********/
- //sorted : [1, 2, 3, 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]
- /********输出结果********/