一。Groovy2.2.0 快速入门:
版本:0.0.1.0
2013-11
下载:https://groovy.apache.org/download.html
1.HelloWorld:
1)配置GROOVY_HOME、path:
2)使用groovyconsole命令打开groovy代码编辑器:
3)GroovyConsole常用命令:
2.数据相关:
def是Groovy中定义变量的常用方法。定义变量时无需指定类型(如同JavaScript),变量所赋值决定其类型。
println/print是Groovy中打印信息到控制台的方法。
1)字符串:
单引号:静态字符串。
双引号:动态字符串。
三引号:字符段,保留既定格式。
反斜杠:转义符。斜杠,非转义符。
字符串操作:
2)数字:
在Groovy中一切皆对象,没有基本数据类型和引用数据类型之分。数字也可以直接调用方法。
3)类:
4)运算符:
(1)计算运算和方法的对应:
(2)比较运算和方法的对应:
(3)方法重写:
3.流程控制语句:
Groovy中流程控制语句的条件类型可以使Boolean、数字、字符串、集合、对象。
※ 当传入Boolean时true为真,false为假;
※ 当传入数字时非0为真,0为假;
※ 当传入字符串时非空为真,空字符串""为假;
※ 当传入集合时长度非0为真,元素个数等于0为假;
※ 当传入普通Object时初始化过为真,null为假。
4.List列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
def list=[1,2,3,3,2,4] println("List 1:"+list) println("List翻倍 :"+list*2) //乘法 println("List等于【1,2,3】:"+(list==[1,2,3])) //相等 println("List添加【5】 :"+(list+[5])) //在末尾添加列表 println("List添加5 :"+(list+5)) //在末尾添加数值 println("List追加5 :"+(list<<5)) //在末尾追加数值 println("List移除【2】 :"+(list-[2])) //移除内容列表.移除全部匹配值 println("List移除3 :"+(list-3)) //移除数值。移除全部匹配值 println("List2Set :"+(list as Set)) //转Set集合,同时会执行去重操作 println("List长度 :"+list.size()) //长度 println("List反转 :"+list.reverse()) //反转 println("List 2:"+list) println("List最大值 :"+list.max()) //最大值 println("List最小值 :"+list.min()) //最小值 println("List中2的个数 :"+list.count(2)) //指定值总数量 println("List元素之和 :"+list.sum()) //全部元素求和 println("List元素自动排序 :"+list.sort()) //排序.这里修改了原始List println("List 3:"+list) println("List去重 :"+list.unique()) //去重。这里修改了原始List println("List 4:"+list) println("List与【2,3,6】没有交集:"+list.disjoint([2,3,6])) //没有交集 println("List与【2,3,7】有交集 :"+!list.disjoint([2,3,7])) //有交集 println("List与【1,7,9,5】的交集:"+list.intersect([1,7,9,5])) //和这个List的交集 list=[1,2,[3,3,2],4] println("List 5:"+list) println("List展开:"+list.flatten()) //子List展开 println("List子元素依次操作:"+list*.plus(1)) //每个元素加1。星号指 对每个元素都进行此操作 |
5.Map集合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
def myMap=[myKey:"我的value"] //初始化时key不带引号 println(myMap) println("myMap==['myKey':'我的value']:"+(myMap==["myKey":"我的value"])) //判断相等 println("myMap.myKey :"+myMap.myKey) //使用.key访问 println("myMap['myKey'] :"+myMap["myKey"]) //使用【“key”】访问 println("myMap.keySet() :"+myMap.keySet()) //查看全部条目的key def youKey="key_your" myMap[(youKey)]="动态的key的value" //添加条目,新key是个变量 println(myMap) println("myMap.keySet() :"+myMap.keySet()) println("myMap.key_your :"+myMap.key_your) println("myMap['key_your'] :"+myMap["key_your"]) println("myMap[(youKey)] :"+myMap[(youKey)]) //通过变量访问指定key的条目 println("myMap.remove('myKey') :"+myMap.remove("myKey")) //删除指定key的条目 println("myMap.myKey :"+myMap.myKey) println("myMap.keySet() :"+myMap.keySet()) println("myMap.remove(youKey) :"+myMap.remove(youKey)) //通过变量名删除指定key的条目 println("myMap.keySet() :"+myMap.keySet()) |
6.Range区间:
一切实现了next()/++和previous()/--方法的类型都可以定义为区间。
1 2 3 4 5 6 7 8 9 |
def rangeClose = 1..6 //闭区间,包括首尾的1和6 def rangeOpen = 1..<6 //开区间,包括首部的1,但不包括尾部的6 println(rangeClose.contains(6)) //是否包含6 println(rangeOpen.contains(6)) println(rangeClose.size()) //长度 println(rangeOpen.size()) println("[*2..6]:"+[*2..6]) //前标星号,区间转List |
7.闭包:
用“{}”包裹起来的代码块。可视其为单个数据或方法,被变量引用。使用时和java的方法一样。
1)基本语法:
使用“->”可以给闭包添加参数;多个参数用逗号隔开;省略“->”可以用关键字“it”这个变量访问;
闭包中可使用“return”确定返回值;如果没有return语句,则最后一行代码为返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//定义一个无参闭包 def 闭包名称={代码块} def closure1={ println it; //关键字“it”是参数接收者 println("在闭包closure1中") } //定义一个有参的闭包 def 闭包名={参数,参数,参数 -> 代码块} def closure2={ args -> println args; 990999 //省略了“return”,这是返回值 } //使用“.call()”调用无参闭包,但传入参数。这个参数由“it”接收 closure1.call("Hello") //也可以如下直接闭包名传参 //调用有参闭包,直接传入参数。参数由闭包中自定义的“args”接收 closure2("Groovy") //也可以如上使用.call调用 println("返回:"+closure2("哈哈,Groovy")) //打印闭包返回值 |
2)delegate闭包代理:
每个闭包都有一个“delegate”属性,指定其代理对象。
闭包可以直接访问这个代理的成员方法和成员属性,代理也可访问其代表的对象。
默认delegate和this相同,可以收到修改delegate值改变其它对象的方法和属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//定义一个全局类 class Foo{ Foo(){ println("构造方法") } def method(i){ println i+",调用Foo的method方法" } //Foo内部的闭包,参数类型Closure-闭包 def c1 = { Closure c -> println("delegate.class:"+delegate.class) //Foo println("this:"+this) //Foo println("delegate == this:"+(delegate == this)) //传入闭包参数时才执行,null则不执行 if(c){ println("c.delegate.class:"+c.delegate.class) c.delegate = this //把参数闭包的代理设为Foo,this == Foo c() //执行作为参数传入的闭包 } } } //实例化类对象 def foo = new Foo() //执行构造方法 foo.method(0) //执行method方法 //定义一个全局闭包 def c2 = { println("delegate.class:"+delegate.class) method(1) //只有当闭包c2的代理为Foo时,才可以调用Foo的内部方法 } //执行类的内部闭包 foo.c1(c2) //调用全局闭包。因为当foo.c1(c2)执行后,c2的delegate指定为了Foo,所以可执行method c2() |
3)闭包操作:
GDK中常见的以闭包为参数的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
//----------List、Map、Range的each方法---------- def c1 = { args -> println("使用闭包打印区间:"+args) } def range1 = 1..5 range1.each(c1) //区间将每个元素传入闭包 //----------findAll方法---------- def c2 = { args -> args > 3 //如果为真,返回这个参数值 } def range2 = 1..5 def arr = range2.findAll(c2) //区间将每个元素传入闭包 println(arr) //----------collect方法---------- def c3 = { args -> args + 3 //对每个参数执行此操作后返回 } def range3 = 1..5 def arr2 = range3.collect(c3) //区间将每个元素传入闭包 println(arr2) //----------any/every方法---------- def c4 = { args -> args > 3 //每个传入的参数都进行判断 } def range4 = 1..5 def boolean1 = range4.any(c4) //至少有一个参数符合条件即true println(boolean1) def boolean2 = range4.every(c4) //全部参数符合条件才true println(boolean2) //----------普通方法转闭包---------- //定义一个方法 def function (){ println("Hello Closure") } //定义一个闭包引用方法 def c = this.&function c() println(this) //当前全局父类ConsoleScript |
二。Groovy2.4.0更新
2014-11
1:新版中数字运算改变和关系运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
//------------------数字运算部分------------------------ def num1 = 1 // 一般运算表达式 def num2 = 2 + num1 println(num2) // 3 // 数字默认是Integer类的实例,可直接调用方法 num2 = 4.plus(num1) // 相加 println(num2) // 5 num2 = num2 / ( num1 + 1 ) println(num2) // 2.5 num2 = 6.div(3) // 早版本的 divide 方法改为 div 。6/3 println(num2) // 结果为整数 2,而不是浮点数 2.0 num2 = 5.multiply(9) // 乘法 5*9 println(num2) // 45 num2 = 5.minus(9) // 减法 5-9 println(num2) // -4 num2 = 15.mod(9) // 取余 5%9 println(num2) // 6 num2 = 13.intdiv(5) // 取商的整数位 println(num2) // 2 num2 = num2++ println("先赋值,后++ :" + num2) // 2 num2 = ++num2 println("先 ++,后赋值:" + num2) // 3 num2 = num2.next() // 同 ++num2,先++改变自己,然后赋值 println(num2) // 4 num2 = num2.next() println(num2) // 5 //-------------------关系表达式------------------------- def num3 = 24 def num4 = 24 println(num3.equals(num4)) // 判断值相等,同 == 。true println(num3 == num4) // 两个值是否相等 true println(!num3.equals(num4)) // 判断值不相等 false println(num3 <=> num4) // 0,比较大小。num3大于num4返回1,num3小于num4返回-1,相等返回0 println(num3.compareTo(num4)) // 0,比较大小,同 <=> |
2:字符串复习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
def str1 = '凤姐' def str2 = "${str1}是NB的" // 如果变量后无空格,用大括号包裹变量名 println(str2) // 凤姐是NB的 def str3 = '${str1}是NB的' // 静态字符串中引用变量无效 println(str3) // ${str1}是NB的 str2 = "$str1 是无敌的" // 如果变量后有空格,可省略大括号 println(str2) // 凤姐 是无敌的 str2 = "芙蓉姐姐" def str4 = "\${str2}照耀我们去'奋斗'" println(str4) // ${str2}照耀我们去'奋斗' def str5 = "${str2}照耀我们去'奋斗'" println(str5) // 芙蓉姐姐照耀我们去'奋斗' str5 = """${str2} 照耀我们 去'奋斗'""" println(str5) // 三引号保留文本的格式,如同html中的<pre> /* 芙蓉姐姐 照耀我们 去'奋斗' */ |
3:基本输入输出
1)print和println
这两个方法和Java中的一样。
1 2 3 4 5 6 7 8 9 10 11 12 |
print("不换行") print(",接着") println() // 换行 println("行内换行\n结尾自动换行") def str = "'插入的'" println('${str}') print("${str}" + "\n") print("${str}" + "\n") |
2)printf格式化输出
此方法和C语言类似。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// %d整型 printf("%d + %d = %d \n", 1, 2, 1+2) // 1+2=3 printf("%d + %d = %d \n", [1, 2, 1+2] ) // 标准写法 // %f浮点 printf("%f + %f = %f \n", 1.0, 2.0, (1.0+2.0)) // 1.000000 + 2.000000 = 3.000000 printf("%f + %f = %.2f \n", 1.0, 2.0, (1.0+2.0)) //保留2位小数:1.000000 + 2.000000 = 3.00 // %s字符串 printf("%s是美女\n", "凤姐") // 默认按照参数打印 printf("%5s是美女\n", "ABC") // 参数字串占5个字符的位置,字串不足5位,左侧补空格 printf("%-5s是美女\n", "A凤姐C") // 右侧补空格,似乎一个汉字占一位 |
3)System.in输入
1 2 3 4 5 6 7 8 9 |
print("输入名字:") name = new BufferedReader(new InputStreamReader(System.in)).readLine() println("你的名字是:" + name) print("输入年龄:") def age = new BufferedReader(new InputStreamReader(System.in)).readLine() println("你的年龄是:" + age) |
4:方法(函数)复习
1)无参函数
(1)形式1:
1 2 3 4 5 6 7 8 |
// 1.定义函数 def func(){ // 使用def声明,紧跟函数名,而后是(),函数体用{}包裹 println("这是个无参函数") } // 2.调用函数 func() |
(2)形式2:
1 2 3 4 5 6 7 |
def func(){ // 同一行内的语句之间用 ; 隔开 print("这是个");println("无参函数") } func() |
(3)形式3:
1 2 3 4 5 6 7 |
def func(){ println("这是个") // 默认每行一个语句 println("无参函数") } func() |
2)方法和变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
def out = 10 // 不用def声明的变量,默认由binding修饰 outer = 11 def func(){ // 1.变量。作用域仅在此函数内 def str = "无参函数" // 2.引用变量 println("这是个${str}" + "..." + str) // println(out) // 默认访问不到函数外面def的变量 // 可以访问到,同:println(binding.outer) println(outer) // 11 } func() // 这是个无参函数...无参函数 // println(str) // 访问不到函数内的变量 println(out) println(outer) //------------------------------ def arg = 1 def func(){ def arg = "a" println(arg) } func() // a println(arg) // 1 |
3)函数的参数
(1)一个参数
1 2 3 4 5 6 7 8 9 10 |
// 定义带一个参数的方法,括号内直接是参数名 def func(name){ println("你好" + name) } func("MJ") // 直接传入参数值 def name = "Em" func(name) // 传入变量作为参数 func() // 不传参,则默认传入null |
(2)多个参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// 定义带一个参数的方法,括号内直接是参数名 def func(name){ println("你好" + name) } // --------- 多个参数 ------------- def func(name1, name2, name3){ println("\n您好" + name1) println("您好" + name2) println("您好" + name3 + "\n") } func("MJ") // 直接传入参数值 def name = "Em" func(name) // 传入变量作为参数 // func() // 没有空参的函数,MethodSelectionException func("MJ", "Eminem", "Alizee") // 自动调用3个参数的方法 func("Sno") // 调用1个参数的方法 |
(3)默认参数
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// --------- 使用默认参数 ------------- def func(name1="SB", name2="二货", name3="脑残"){ println("\n您好" + name1) println("您好" + name2) println("您好" + name3 + "\n") } func() // 全部使用默认参数 func("Sno") // 使用第2和第3个默认参数 func("Sno", "2PUC") // 使用最后一个默认参数 func("Sno", "2PUC", "Eminem") // 改变全部参数 |
(4)默认参数和函数重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
def func(){ println("空参函数") } /**The method with default parameters "java.lang.Object func(java.lang.Object, java.lang.Object, java.lang.Object)" defines a method "java.lang.Object func()" that is already defined. . At [11:1] at line: 11, column: 1*/ // ----- 因为上面有个空参同名函数,本函数第一个参数不能有默认值,否则不传参调用时报错 ------ def func(name1, name2="二货", name3="脑残"){ println("\n您好" + name1) println("您好" + name2) println("您好" + name3 + "\n") } func() // 调用无参的函数。不能有同名有参且第一个参数具有默认值的函数 func("Sno") func("Sno", "2PUC") func("Sno", "2PUC", "Eminem") |
(5)参数传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
def arg = "a" def func (args) { args = "b" println(args) } func(arg) // b println(arg) // a //------------------------- def list = ["b", "a", "d", "c"] println(list) // 原List集合:[b, a, d, c] def func1 (ls, doSort = true) { if(doSort){ ls.sort() // 改变了原List } println(ls) } func1(list) // [a, b, c, d] println(list) // 原List集合:[a, b, c, d] |
4)函数返回值
(1)return
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def func(){ println("使用函数的返回值") } // 没有使用return返回值,默认null println(func()) /**使用函数的返回值 null */ def func1(){ println("使用函数的返回值") return "这是返回值" } println(func1()) /** 使用函数的返回值 这是返回值 */ |
(2)隐式返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def func1(){ println("使用函数的返回值") // 没有使用return关键字,但只要最后一行是一个有效数据,即返回 "这是返回值" } println(func1()) /** 使用函数的返回值 这是返回值 */ def func2(){ println("使用函数的返回值") (1+2)*3/4 } println(func2()) /** 使用函数的返回值 2.25 */ |
5:流程控制复习
1)if 条件语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
if(''){ // "" 、'' 都为 false println("有东西") }else{ println("没东西") // 打印 } def str = 'a' if(str){ println("有东西") // 打印 }else{ println("没东西") } if(0){ // 0 为 false println("有东西") }else{ println("没东西") // 打印 } |
2)for 循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
def str = "dagdsaghdfd" def rge = 1..9 def rge2 = 1..<9 // 不包含9 def list = ['ad', 'sg', 'dg'] def map = ['a':4, 'b':4, 'g':0] for(i in str){ print(i + " ") //d a g d s a g h d f d } println() for(i in rge){ print(i + " ") //1 2 3 4 5 6 7 8 9 } println() for(i in rge2){ print(i + " ") //1 2 3 4 5 6 7 8 } println() for(i in list){ print(i + " ") //ad sg dg } println() for(i in map){ print(i.key + "-" + i.value + " ") //a-4 b-4 g-0 } |
3)while循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def str = "hlksflkhfhs" def rge = 1..9 while (str) { // str = str.previous() // 同 -- ,按照ASCII码运算 str = str.minus(str.getAt(str.length()-1)) // 移除最后一个字符 println(str) } def i = 1 while (i in rge) { println(i) i++ } |
4)switch选择/开关
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
def num = 1 switch(num){ case 1: // 如果num == 1 println("1") break // 不中断,将继续向下判断 case 2: println("2") break } switch(num){ case 1..3: println("在1-3之间") // 打印 break case 4..6: println("在4-6之间") break } switch(num){ case [1,2,3]: println("在1,2,3之间") // 打印 break case [4,5,6]: println("在4,5,6之间") break } def str = 'a' switch(str){ case "abcd": println("在abcd之间") case ["a", "b", "c"]: println("在a,b,c之间") // 打印 break case [4,5,6]: println("在4,5,6之间") break } |
5)break和continue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
def lst1 = [4,56,7,5,4] def lst2 = ['fdsg', 'afd', 'hg', 'z'] for (i in lst1) { print(i + "\t") for (j in lst2) { print(j + " ") } println() } println("11111111111111111111111111111111") for (i in lst1) { print(i + "\t") if (i == 7) break // 当遍历到7时,终止外循环,整个循环体结束 for (j in lst2) { print(j + " ") } println() } println("\n22222222222222222222222222222222") for (i in lst1) { print(i + "\t") if (i == 7) continue // 当遍历到7时,跳过下面的子循环和换行。继续外循环,遍历集合中的下一个数值5 for (j in lst2) { print(j + " ") } println() } println("\n3333333333333333333333333333333333333") outside: for (n = 0; n<9; n++){ println("\n------------" + n) center: for (i in lst1) { print(i + "\t") if (i == 7) continue outside // 当遍历到7时,即跳转到指定名称的最外层循环,下面的子循环永远不执行 inside: for (j in lst2) { print(j + " ") } println() } } |
6:闭包复习
1)闭包参数
(1)无参闭包
1 2 3 4 5 6 7 8 9 10 |
// 闭包名称={闭包体} def closure = { println("Hello Closure !") } // 调用闭包 closure.call() // 闭包也是对象,使用其call方法执行闭包 closure() // 省略写法 |
(2)有参闭包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
//--------- 一个参数 ----------- def closure = { param -> println("Hello ${param} !") } closure.call("Eminem") // Hello Eminem ! closure("Alizee") // Hello Alizee ! //--------- 多个参数 ------------ def closure2 = { param1, param2, param3 -> println("你好 ${param1} !") } // 闭包要求3个参数,必须传入3个 closure2.call("WWW", ".", "CuiWeiyou") // 你好 WWW ! closure2("Vigiles", "NOTORIOUS B.I.G", "2Pac") // 你好 Vigiles ! //--------- 参数默认值 ------------ def closure3 = { param1, param2="KORN", param3="MARILYN MANSON" -> println("啥么 ${param1} !") } // 闭包要求3个参数,必须传入3个 closure3.call("grailscn", "www", "com") // 啥么 grailscn ! closure3("beardap", "熊跳") // 啥么 beardap ! closure3("熊跳游戏") // 啥么 熊跳游戏 ! // closure3() // 必须至少有一个参数,因为第一个参数没有默认值 //--------- 默认参数 it ----------- def closure4 = { // 这里有个默认的参数 // it -> println("看看默认的 ${it} !") } closure4("GrailsCN") //看看默认的 GrailsCN ! |
(3)参数作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
def arg = "abcdefg" // 闭包外定义的变量 def closure = { param -> println("Hello ${param} !") } closure(arg) // Hello abcdefg ! arg = "higklmn" closure(arg) // Hello higklmn ! arg = "opqrst" def closure2 = { param -> param = "uvwxyz" // 不能改变闭包外定义的变量 println("Hello ${param} !") } closure2(arg) // Hello uvwxyz ! println(arg) // opqrst,没有被闭包改变 def closure3 = { // arg -> arg = "Haha" // 闭包内能访问到外部定义的变量 println("Hello ${arg} !") } closure3(arg) // Hello Haha ! println(arg) // Haha,在闭包内被改变了 |
(4)闭包和方法
1>>有重载方法时的闭包使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
def arg = "abcdefg" //--------- 定义闭包,有一个具有默认值的参数 def closure = { param="闭包" -> println("Hello ${param} !") } //~~~~~~~~~ 定义方法,无参 def func () { println("\n-----------------无参的方法") } //~~~~~~~~~ 定义方法,须要1个参数 def func ( clos ) { println("\n-----------------1参的方法") clos.call() // 通过call可以看出这个参数是个闭包 } //~~~~~~~~~ 重载方法,须要2个参数 def func ( clos, arg ) { println("\n-----------------2参的方法") clos.call(arg) } //\\\ 调用方法,传入一个闭包 func(closure) //// 1参 Hello 闭包 ! //\\\ 调用方法,传入一个闭包和一个字串 func(closure, "我是闭包") //// 2参 Hello 我是闭包 ! //\\\ 直接传入一个闭包作为参数 func( { println("你好,小沈阳") } ) //// 1参 你好,小沈阳 func( { println("你好 ${it}") }, "我是默认it" ) //// 2参 你好 我是默认it //==================== 如果方法的参数是闭包,可以写在括号外面 //\\\ 直接传入一个闭包作为参数 // 似乎是再括号外不能判断closure类型。调用了无参的方法 //func() closure // 无参 MissingPropertyException: No such property: clos for class: //\\\ 这个闭包可以传给有一个参数的方法 func() { println("你好翠花") } //// 1参 你好翠花 //\\\ 以下两种都错误 //func [{ println("你好 ${it}") }, "List"] //func {{ println("你好 ${it}") }, "Map"} |
2>>闭包作为参数的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
def arg = "abcdefg" def closure = { param -> println("Hello ${param} !") } def func (clos) { clos.call("这个clos") } def func2 ( arg, clos ) { // 此方法的闭包参数在后面 clos(arg) } func(closure) //// Hello 这个clos ! func2("我是闭包", closure) //// Hello 我是闭包 ! func ({ println("你好,小沈阳") } ) //// 你好,小沈阳 func2( "我是默认it", { println("你好 ${it}") } ) //// 你好 我是默认it // 闭包放在括号外 func() { println("你好翠花,${it}") } //// 你好翠花,这个clos // 省略方法的括号 func { println("你好翠花2,${it}") } //// 你好翠花2,这个clos // 闭包为最后一个参数,可以放在括号外 func2("一般参数在前,闭包垫后"){aa -> println(aa)} //// 一般参数在前,闭包垫后 |
2)闭包常用之处
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// "abcdefg".each(){ // 同下 // 给each方法传入一个闭包作为参数 "abcdefg".each{ print(it + " ") } // a b c d e f g println() [4,5,6,6,3,2].each{ print(it + " ") } // 4 5 6 6 3 2 println() ["n":114, "p":65, "q":112].each{ print(it.key + ":" + it.value + " ") } // n:114 p:65 q:112 println() ["aaa":"AAA", "bbb":"BBB", "ccc":"CCC"].each{ arg1, arg2 -> print( arg1 + arg2 + " ") } // aaaAAA bbbBBB cccCCC println() [["xxx":"XXX"]:1, ["yyy":"YYY"]:2, ["zzz":"ZZZ"]:3].each{ arg1, arg2 -> print(arg1.keySet() + arg1.values() + arg2 + " ") } // [xxx, XXX, 1, ][yyy, YYY, 2, ][zzz, ZZZ, 3, ] println() def num = [4,5,6,6,3,2].findAll{ it > 5 // 查找并返回大于5的数 } println(num) // [6, 6] num = [4,5,6,6,3,2].any{ it > 5 // 只要有大于5的数,即返回true } println(num) // true num = [4,5,6,6,3,2].every{ it > 5 // 必须全部大于5,才返回true } println(num) // false num = [4,5,6,6,3,2].collect{ // 遍历结合 it += 5 // 遍历集合元素,每个元素+5 } println(num) // [9, 10, 11, 11, 8, 7] num = [4,5,6,6,3,2].inject(0){ // 注入。遍历集合 a,b -> // a接收注入的0,只注入一次。b接收遍历的集合元素 a += b // 变量集合元素,累加元素 } println(num) // 26 |
3)闭包排序例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// 闭包,接收一个集合参数 def selectionSort = { list -> // 内部闭包,接收一个集合,和一个位置 def minimumPostion = { pList, from -> def mPos = from // 比较数 的位置 def nextFrom = from +1 // 下一个位置 // 比较数 和集合的一段距离内进行比较 for ( j in nextFrom..<pList.size()) { if ( pList[j] < pList[mPos] ) { mPos = j // 获得 比较数 的位置到集合末尾,最小数的位置 } } return mPos } // 内部闭包,接收一个集合,两个位置p=最小数字位置,q=遍历到的数字位置 def swap = { sList, p, q -> def temp = sList[p] sList[p] = sList[q] sList[q] = temp // 把这个集合中的这两个位置的数值交换 } def size = list.size() - 1 // 遍历集合。第一次遍历,第一个成为最小的数字;第2此遍历,第2个位置成为稍微最小的;... for (k in 0..<size) { // 从第一个数,开始和全集合比较,返回最小数字的位置 def minPos = minimumPostion(list, k) // 将最小数字和当前数字位置替换 swap(list, minPos, k) } return list } def tab = [23, 43, 3, 21, 9] def sorted = selectionSort(tab) println(sorted) // [3, 9, 21, 23, 43] |
7:类的复习
1)类的创建和属性操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* 关键字:class // 紧跟类名 // 紧跟大括号 */ class MyClass { // def 声明属性。默认是 public def property1 def property2 } /** 1.实例化类 */ // 此例如同构造方法,直接操作属性 def myClass1 = new MyClass(property1:"属性1值", property2:"属性2值") /** 使用实例 **/ println(myClass1.property1 + "," + myClass1.property2) // 属性1值,属性2值 /** 2.实例化类 */ def myClass2 = new MyClass(property1:"属性1值") println(myClass2.property1 + "," + myClass2.property2) // 属性1值,null /** 3.实例化类 */ def myClass3 = new MyClass() myClass3.property1 = "Alizee" myClass3.property2 = "Eminem" println(myClass3.property1 + "," + myClass3.property2) // Alizee,Eminem |
2)类方法
(1)方法示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class MyClass { def property1 def property2 def func1 () { println("func1:类内无参函数。" + property1) } /** 方法重载 **/ def func1 (arg) { println("func1:类内1参函数。" + arg) } def func2 (arg) { println("func2:类内1参函数:${arg}") } } def myClass1 = new MyClass(property1:"属性1值", property2:"属性2值") myClass1.func1() // func1:类内无参函数。属性1值 myClass1.func1("看看") // func1:类内1参函数。看看 myClass1.func2("MJ") // func2:类内1参函数:MJ myClass1.func2() // func2:类内1参函数:null //myClass1.func2("xxx", "ooo") // groovy.lang.MissingMethodException |
(2)类的toString方法示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class MyClass { def property1 def property2 // 明确定义了返回值类型 String toString () { // 最后一行作为一个有效数据,可以省略 return "MyClass:[property1=${property1}, property2=${property2}]" } } def myClass1 = new MyClass(property1:"Alizee", property2:"Eminem") def myClass2 = new MyClass(property1:"MJ", property2:"2Pac") def mes = [myClass1, myClass2] println(mes) // [MyClass:[property1=Alizee, property2=Eminem], MyClass:[property1=MJ, property2=2Pac]] // 使用集合的each方法,通过 闭包 遍历元素 mes.each{ // element接收每一个元素 element -> println(element) } //MyClass:[property1=Alizee, property2=Eminem] //MyClass:[property1=MJ, property2=2Pac] |
(3)构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
class MyClass { def property1 def property2 // 构造方法无 def 声明 // 名称和类相同 // 可以重载 MyClass(){ // 默认无参构造方法 } MyClass(property1, property2){ // 重载的有参构造方法 // 本类属性 = 参数 this.property1 = property1 this.property2 = property2 } String toString () { "MyClass:[property1=${property1}, property2=${property2}]" } } // 这个传入了指定属性的值,调用默认无参构造方法 def myClass1 = new MyClass(property1:"Alizee", property2:"Eminem") // 这个直接传值,调用有参构造方法 def myClass2 = new MyClass("MJ", "2Pac") def mes = [myClass1, myClass2] mes.each{ element -> println(element) } // MyClass:[property1=Alizee, property2=Eminem] // MyClass:[property1=MJ, property2=2Pac] |
(4)类的调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
// 学生,有姓名、年龄 class Student { def String name def Integer age String toString () { "学生:[姓名=${name}, 年龄=${age}]" } } // 老师,有姓名,学生名单 class Teacher { def name def stus=[] // 集合 // 学生计数 def addStu (name, age) { // 来一个,加一个 def stu = new Student(name:name, age:age) stus += stu } String toString () { "老师:[姓名=${name}, 学生=${stus.size()}]" } } def teacher = new Teacher(name:"老王") teacher.addStu("翠花", 12) teacher.addStu("翠花2", 13) teacher.addStu("翠花3", 14) teacher.addStu("翠花4", 15) println(teacher) // 老师:[姓名=老王, 学生=4] |
8:类的继承、抽象类、接口
1)使用extends关键字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
class Animal { def foot def ear def eat () { println("动物吃东西") } String toString () { "Animal[脚:${foot},耳朵:${ear}]" } } // 使用关键字 extends 继承 class Dog extends Animal { // def foot // // def ear // 尽管Dog没有声明ear,但从Animal中继承了来 def booty def bark () { println("狗狗汪汪叫") } // 此方法和父类中同名,重写 String toString () { super.toString() + ", Dog[屁股:${booty}]" } } def aml = new Animal(foot:4, ear:2) aml.eat() // 动物吃东西 println(aml) // Animal[脚:4,耳朵:2] def dog1 = new Dog(booty:"有尾巴") dog1.bark() // 狗狗汪汪叫 dog1.eat() // 动物吃东西 println(dog1) // Animal[脚:null,耳朵:null], Dog[屁股:有尾巴] def dog2 = new Dog(foot:4, ear:2, booty:"有尾巴") dog2.bark() // 狗狗汪汪叫 dog2.eat() // 动物吃东西 println(dog2) // Animal[脚:4,耳朵:2], Dog[屁股:有尾巴] println(dog2.ear) // 2 |
2)抽象类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// 抽象类,使用abstract关键字 abstract class Animal { def foot def ear def abstract eat () // 声明一个抽象的方法,具体何种功能,由子类实现 String toString () { "抽象Animal[脚:${foot},耳朵:${ear}]" } } // 使用关键字 extends 继承 class Dog extends Animal { def booty // 子类必须实行抽象父类的抽象方法 def eat () { println("狗狗吃饭") } // 此方法和父类中同名,重写 String toString () { super.toString() + ", 具象Dog[屁股:${booty}]" } } // def aml = new Animal(foot:4, ear:2) // 抽象类不能被实例化 def dog1 = new Dog(booty:"有尾巴") dog1.eat() // 动物吃饭 println(dog1) // 抽象Animal[脚:null,耳朵:null], Dog[屁股:有尾巴] def dog2 = new Dog(foot:4, ear:2, booty:"有尾巴") dog2.eat() // 动物吃饭 println(dog2) // 抽象Animal[脚:4,耳朵:2], 具象Dog[屁股:有尾巴] println(dog2.ear) // 2 |
3)接口
接口是规范,是协议。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// 接口。interface后直接跟名称 interface IWantBeProgramer { // 接口定义属性无意义,只定义方法 def abstract programming () def abstract projecting () } // 使用关键字 implements 实现接口 class Me implements IWantBeProgramer { def age // 年龄 def diploma // 学历 // 实现接口定义的 全部 方法 def programming () { println("敲代码") } def projecting () { println("做项目") } String toString () { "我[${age},${diploma}]是个程序员" } } def me = new Me(age:87, diploma:"文盲") println(me) |
9:数据库(MySql)简单操作
本例使用 GroovyConsole ,须要先将 mysql 的驱动 jar 包(mysql-connector-java-5.1.26-bin.jar)放入 %groovy-2.4.0-beta-3%\lib 目录中。mysql版本mysql-5.6.16-winx64。
1)简单查询:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import groovy.sql.Sql // 数据库路径 def db = "jdbc:mysql://localhost:3306/db_groovy" // 用户 def user = "root" // 密码 def pswd = "root" // 数据库驱动 def driver = "com.mysql.jdbc.Driver" // 数据库实例 def sql = Sql.newInstance(db, user, pswd, driver) // 将查询出的条目遍历 sql.eachRow("select * from tb_groovy"){ row-> println(row) } |
[name:Alizee, description:法国女歌手, _id:1]
[name:Eminem, description:美国说唱歌手, _id:2]
[name:N.Big, description:美国说唱歌手, _id:3]
[name:Michael Jackson, description:美国流行歌王, _id:4]
2)简单关系查询:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import groovy.sql.Sql def db = "jdbc:mysql://localhost:3306/db_groovy" def user = "root" def pswd = "root" def driver = "com.mysql.jdbc.Driver" def sql = Sql.newInstance(db, user, pswd, driver) // 将查询出的条目遍历 // where description = ? 为查询条件,?即条件值 // ["非常喜欢"] 为对应?的条件值集合,有几个?,集合内就对应传入几个值 sql.eachRow("select * from tb_like where description = ?", ["非常喜欢"]){ // 查询到的条目轮询 row-> // 调用条目的列名 println(row.groovy_id) } println("--------------------------------") // 根据两个表的关系进行有条件查询 sql.eachRow("select g.name, l.description " + "from tb_groovy g, tb_like l " + "where g._id = l.groovy_id and l.description = ?", ["非常喜欢"]) { row-> println(row.name + "=" + row.description) } |
3)常规增、删、改:
1 2 3 4 5 6 7 8 9 10 |
// 插入 sql.execute("insert into tb_groovy(name, description) values('芙蓉姐姐', '中国最励志人物')") // 删除 sql.execute("delete from tb_groovy where _id = ?", [5]) // 更新 sql.execute("update tb_groovy set name = ? where _id = ?", ["MJ", "4"]) |
4)DataSet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import groovy.sql.Sql def db = "jdbc:mysql://localhost:3306/db_groovy" def user = "root" def pswd = "root" def driver = "com.mysql.jdbc.Driver" def sql = Sql.newInstance(db, user, pswd, driver) // 获得数据表的操作器 def tb_groovy = sql.dataSet("tb_groovy") // 直接插入 tb_groovy.add(name:"信凤姐", description:"得永生") println("-----------------") // 遍历每行条目 tb_groovy.each{ row-> println(row) } println("+++++++++++++++++") // 执行sql语句 tb_groovy.execute("insert into tb_groovy(name, description) values('百元哥', '也是极品')") // 得到全部条目,再遍历 tb_groovy.rows().each{ println(it) } println("=================") // 得到第一行 println(tb_groovy.firstRow()) println("~~~~~~~~~~~~~~~~~") |
-----------------
[name:Alizee, description:法国女歌手, _id:1]
[name:Eminem, description:美国说唱歌手, _id:2]
[name:N.Big, description:美国说唱歌手, _id:3]
[name:MJ, description:美国流行歌王, _id:4]
[name:芙蓉姐姐, description:中国最励志人物, _id:6]
[name:信凤姐, description:得永生, _id:7]
+++++++++++++++++
[name:Alizee, description:法国女歌手, _id:1]
[name:Eminem, description:美国说唱歌手, _id:2]
[name:N.Big, description:美国说唱歌手, _id:3]
[name:MJ, description:美国流行歌王, _id:4]
[name:芙蓉姐姐, description:中国最励志人物, _id:6]
[name:信凤姐, description:得永生, _id:7]
[name:百元哥, description:也是极品, _id:8]
=================
[name:Alizee, description:法国女歌手, _id:1]
~~~~~~~~~~~~~~~~~
10:简单网络编程
1)tomcat准备:
本例使用 apache-tomcat-8.0.3,在 \webapps 里新建 GroovyServer 文件夹,在 \GroovyServer 中再新建 WEB-INF,在 \WEB-INF 里再新建 lib 。
形成目录:%apache-tomcat-8.0.3%\webapps\GroovyServer\WEB-INF\lib
(1)从 groovy 安装目录的 lib 里,至少拷贝:
groovy-2.4.0-beta-3.jar
groovy-json-2.4.0-beta-3.jar
groovy-servlet-2.4.0-beta-3.jar
groovy-templates-2.4.0-beta-3.jar
groovy-xml-2.4.0-beta-3.jar
5个jar包放入新建的 %apache-tomcat-8.0.3%\webapps\GroovyServer\WEB-INF\lib 中
一般的直接将 %Groovy%\lib 中的 jar 全部拷贝 到 %apache-tomcat-8.0.3%\webapps\GroovyServer\WEB-INF\lib 即可。
(2)在 %apache-tomcat-8.0.3%\webapps\GroovyServer\WEB-INF 里新建 web.xml 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="utf-8"?> <web-app> <servlet> <servlet-name>GroovyServlet</servlet-name> <!-- 和Java的Servlet是一个性质的 --> <servlet-class>groovy.servlet.GroovyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>GroovyServlet</servlet-name> <url-pattern>*.groovy</url-pattern> </servlet-mapping> </web-app> |
2)创建 groovy 程序
新建 hellogroovy.groovy 文件,放在 %apache-tomcat-8.0.3%\webapps\GroovyServer 里。
这个 groovy 和 java 的 servlet 如出一辙。注意编码格式为 utf-8无bom。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
println ( """ <html> <head> <title>Hello Groovy !</title> </head> <body> <p> 这里是在tomcat服务器中的groovy文件<br/> 你须要从浏览器中这样访问:[url]http://127.0.0.1:8080/[/url]项目/*.groovy </p> </body> </html> """ ) |
3)访问:
1> 调用 %apache-tomcat-8.0.3%\bin\startup.bat 文件,启动服务器,
2> 从浏览器访问 http://127.0.0.1:8080/GroovyServer/hellogroovy.groovy
4)使用GSP页面文件:
(1)新建 hellogroovy.gsp 文件:
gsp文件即一个html文件,性质如同jsp。
本例中出现中文就会乱码,经过各种设置为utf-8。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<html> <head> <title>Hello Groovy</title> <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> </head> <body> <p>used like jsp, this is gsp file</p> <p> we used groovy bat like this :<br/> <% println 'hello gsp' %> <br/> <% println 'hello gsp' %> </p> </body> </html> |
(2)修改 web.xml :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?xml version="1.0" encoding="utf-8"?> <web-app> <servlet> <servlet-name>GroovyServlet</servlet-name> <!-- Groovy中处理.groovy文件 --> <servlet-class>groovy.servlet.GroovyServlet</servlet-class> </servlet> <servlet> <servlet-name>TemplateServlet</servlet-name> <!-- Groovy中处理.gsp文件。中文乱码是这个的原因? --> <servlet-class>groovy.servlet.TemplateServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>GroovyServlet</servlet-name> <url-pattern>*.groovy</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TemplateServlet</servlet-name> <url-pattern>*.gsp</url-pattern> </servlet-mapping> </web-app> |
(3)访问页面:
- end
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/1316.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设