Groovy
简介
Groovy
是一种DSL语言
DSL
的全称是Domain Specific Language
,即领域特定语言,或者直接翻译成“特定领域的语言”,其实就是这个语言不通用,只能用于特定的某个领域,俗称“小语言”。因此DSL也是语言。
- 是一种基于
JVM
的敏捷性开发语言 - 结合
Python、Ruby与Smalltalk
的许多强大特性 - 可以与Java完美结合,并且可以使用Java中所有的库
特性
- 语法上支持动态类型、闭包等新一代语言特性
- 无缝衔接所有已经集成的Java库
- 不仅支持面向对象编程,也支持面向过程bianc
优势
- 一种更加敏捷的编程语言
- 入门简单,功能强大
- 不仅可以作为编程语言,也可以作为脚本语言
变量及定义
Groovy 变量类型分为基本类型与对象类型,定义分为强类型定义与弱类型定义 强类型定义:使用一个具体的类型,例如int x = 10 弱类型定义:使用一个def作为变量的修饰符,例如 def y = 10.9
//强类型定义的就是一个具体的类型
int x=10
double y = 10
//println x.class
//println(y.class)
//def 定义的是一个弱类型,就是object类型
def x_1 = 10
def u_1 = 23.4
def s = "cxm"
//可以重新赋值成string字符串类型
x_1 = "yif"
println(x_1.class)
println(u_1.class)
println(s.class)
String 用法
String 中使用了三种不同的引号进行定义变量
- 单引号进行定义字符串
- 两个单引号及双引号定义字符串可以进行扩展输出内容
- 三个单引号进行定义字符串可以格式化输出
def name = 'this is \'a\' name'
//println name.class
//用三个单引号来进行定义string类型,可以格式化输出字符串
def thuplename = '''this is name'''
def linename = '''\
line one
line two
line three
'''
//双引号定义的字符串可以扩展
def doublename = "this is name"
def kuoname = "name"
def helloname = "hello $kuoname"
println helloname
//输出class org.codehaus.groovy.runtime.GStringImpl
println helloname.class
//println doublename
//println linename
//println thuplename.class
def sum = "the sum of 2 and 3 is Equals ${2+3}"//可以扩展任意的表达式
println sum
def result = echo(sum)
println result
//Groovy 编译器直接将GStringImpl类型转换成String 类型输出
println result.class
String echo(String msg){
return msg
}
String 常用API
/* ====== 字符串方法 ====== */
//1. 字符串填充
def str = "groovy hello"
//center 进行填充字符串,总共字符串长度为8 以当前字符串为中心向两边进行填充
println str.center(9, "a")
//将字符串追加到当前字符串左边
println str.padLeft(8, "a")
//2. 字符串比较
def str2 = "hello"
//使用方法
println str2.compareTo(str)
//使用操作符
println str2 > str
//3. 索引:获取字符串中的某个索引
//通过方法获取
println str2.getAt(1)
//通过中括号传入下标进行获取
println str2[1]
//传入一个范围获取字符串中的值,前后都包括
println str2[0..1]
//4. 字符串加减操作
//如果一个字符串中包含另一个字符直接相减 就获取减去的字符,不包括,则还是原来字符
println str.minus(str2)
println str.reverse()
//对字符串进行首字母大写
println str.capitalize()
循环结构使用
- Switch 使用与Java类型,但在Groovy中又新加了许多新的声明,可以进行列表与数组或者类型的输出
- for 循环与Java类似
//1. switch 使用
def result = 10
def x = 100
switch (x){
case 123:
result = 123
break
case '123':
result = '123'
break
case [10.12,1,2,3,"hi"]://列表
result = 'list'
break
case 1..23://数组
result = 'range'
break
case Integer:
result = "Integer"
break
case BigDecimal:
result = "BigDecimal"
break
default:
result = 'default'
break
}
println result
//2. 对范围的for循环
def sum = 0
for(i in 0..9){
sum += i
}
println sum
//对list的循环
sum = 0
for(i in [12,23,35,45]){
sum += i
}
println sum
//对map进行循环
sum = 0
for(i in ["lili":3,"yif":23,"cmx":34]){
sum += i.value
}
println sum
闭包
Groovy
中有一种特殊的类型,叫做Closure
,翻译过来就是闭包,这是一种类似于C语言中函数指针的东西。闭包用起来非常方便,在Groovy
中,闭包作为一种特殊的数据类型而存在,闭包可以作为方法的参数和返回值,也可以作为一个变量而存在。
声明闭包:
例如:
def a = {
//大括号中进行代码的操作输出,如果需要变量可以进行变量声明
String name ->
}
调用闭包:
- 直接变量加括号进行调用
- 通过方法名加call方法进行调用
闭包一定有返回值,但不加return返回值为null
def clouser = {println 'hello groovy'}
//调用闭包
clouser.call()
//或者通过变量加括号进行调用
clouser()
//闭包中增加参数
def clouserresult = {String name -> println "hello ${name}"}
clouserresult.call('yif')
def name = 'ztz'
clouserresult('yif')
clouserresult(name)
//传入多个参数
def clouserresulttwo = {String tip,Integer age -> println "hello ${tip},and age is $age"}
clouserresulttwo('yif',25)
//闭包默认参数it
def test = {println "hello $it"}
test('yyy')
//闭包一定有返回值
//def returnresult = { String a -> return "hello $a"}
//不加return 也有返回值 值为 null
def returnresult = { String a -> println "hello $a"}
def cosule = returnresult('cxv')
println cosule
闭包用法
- 与基本类型进行结合使用
- 与String 类型进行结合使用
- 与数据结构结合使用
- 与文件结合使用
基本类型使用
阶乘与累加求和
// 闭包作为方法参数的最后一个,可以直接放到外面
def x = 5
println fgb(x)
//实现当前数字的阶乘
int fgb(int number){
int result = 1
//upto 来实现阶乘的乘法,进行循环处理
1.upto(number,{num -> result *= num})
return result
}
//downto 来实现阶乘
int fab(int number){
int result = 1
//闭包放在方法外与里面效果一样
number.downto(1){
num -> result *= num
}
return result
}
println fab(x)
//用times 来实现累加,不能用来实现阶乘,因为源码中是从0开始的
int cal(int number){
int result = 0
number.times {
num -> result += num
}
return result
}
println cal(5)
字符串与闭包结合使用
/**
* 字符串与闭包结合使用
*/
def string = "this is 2 to 4 result 6"
string.each {
//multiply 将每个字符进行翻倍
String tmp -> print tmp.multiply(2)
}
println()
//each 返回值就是调用者本身
println string.each {}
//find 查找第一个满足条件的
println string.find{
String num -> num.isNumber()
}
//findAll 查找所以满足条件的
def list = string.findAll{
String num -> num.isNumber()
}
println list.toListString()
//any 用来判断是否满足某个条件
def anyresult = string.any {
String num -> num.isNumber()
}
println anyresult
//every 用来判断每一项都满足某个条件
def everyresult = string.every {
String num -> num.isNumber()
}
println everyresult
def str = string.collect{it.toUpperCase() }
println str.toListString()
闭包三个重要变量
闭包三个重要变量this owner delegate
默认都是最近的类对象
- 如果在类中或者方法中定义闭包,那么这三个变量输出结果都是一样的
- 如果在闭包中嵌套一个闭包,那么这三个变量结果不一样,this还指向类对象,而
owner与delegate
指向的是最近的闭包对象 - 如果人为的修改
delegate
指向的对象,那么owner与delegate
输出结果就不一样了 this与owner
是不能修改的,一旦定义就明确,而delegate
是可以做任意修改的
def script = {
//这输出的是类的对象
println "script this:" + this//代表闭包定义处的类
println "script owner:"+owner //代表闭包定义处的类和对象
println "script delegate:"+delegate//代表任意对象,默认与owner一致
}
script()
//定义一个内部类
class Person{
//这输出的都是类的字节码,因为是static
def static classClourse = {
println "classClourse this:" + this
println "classClourse owner:"+owner
println "classClourse delegate:"+delegate
}
def static say(){
def classClourse = {
println "method classClourse this:" + this
println "method classClourse owner:"+owner
println "method classClourse delegate:"+delegate
}
classClourse.call()
}
}
Person person = new Person()
//person.classClourse.call()
//person.say()
Person.classClourse.call()
Person.say()
//闭包中定义闭包
def nestClourse = {
def innerClourse = {
println "innerClourse this:" + this
println "innerClourse owner:"+owner
println "innerClourse delegate:"+delegate
}
innerClourse.delegate = person// 修改默认的delegate
innerClourse.call()
}
nestClourse.call()
闭包委托策略
通过委托delegate的方式,来人为的修改原对象属性的值
委托策略Closure.DELEGATE_FIRST
DELEGATE_FIRST
先从委托属性中寻找,没有找到再从owner中寻找;DELEGATE_ONLY
只从委托中寻找,没有就报错
/*
闭包委托策略
*/
class Stu{
String name
def printName = {" my name is $name"}
String toString(){
printName.call()
}
}
class Tea{
String name
}
def stu = new Stu(name: "yif")
def tea = new Tea(name: "fxy")
println stu.toString()
stu.printName.delegate = tea
//修改闭包委托策略,DELEGATE_FIRST先从委托属性中寻找,没有找到再从owner中寻找;DELEGATE_ONLY只从委托中寻找,没有就报错
stu.printName.resolveStrategy = Closure.DELEGATE_FIRST
//如果tea中没有这个变量name,就会从owner中寻找,找到stu中name,输出就是stu中的结果
println stu.toString()
欢迎访问个人博客 Yif博客