系列文章目
Gradle学习之一入门介绍
Gradle学习之二Groovy核心语法
Gradle学习之三Groovy高级语法
Gradle学习之四Gradle生命周期
Gradle学习之五Project详解
Gradle学习之六Task详解
Gradle学习之七其他重要模块
文章目录
一、基础语法
groovy中没有基本数据类型,编译器会将其装箱成对象类型
变量定义 使用def 弱类型方式
弱类型方式声明的变量,其类型可发生改变:
二、String讲解
2.1 三种定义方式
接下来看一下双引号定义的可扩展字符串
扩展字符串中,花括号{}里面可以是任意表达式:
2.2 新增操作符
String方法的来源有三个:String , DefaultGroovyMethods , StringGroovyMethods
而StringGroovyMethods 普通类型参数和闭包类型参数。
//字符串的填充
def str = "groovy"
println str.center(10,"abc")
println str.center(11)
println str.padLeft(8,"a").padRight(11,'a')
//比较字符串
def str2 = "hello"
println str.compareTo(str2)
println str>str2
//访问元素
println str[1]
println str[1,3]
def str3 = "lo"
println str2.minus(str3)
println str2-str3
//翻转
println str2.reverse()
//首字母大写
println str2.capitalize()
//是否是纯数字
println "123213".isNumber()
//类型转化
println '12312312'.toInteger().class
三、逻辑控制
switch语句可以传入哪些类型:
def x = 1.233
def result
//需要注意的是如果传入x.class,此时将会命中BigDecimal;
//如果传入x,且case bigDecimal在case list的前面,将会命中BigDecimal
switch (x) {
case 'foo':
result = 'found foo'
break
case 'bar':
result = 'bar'
break
case [1.233,4,5,6,'inlist']:
result = 'list'
break
case 12..30:
result = 'range'
break
case Integer:
result = 'integer'
break
case BigDecimal:
result = 'big decimal'
break
default:
result = 'default'
break
}
println result
循环的变体:
//for循环变体
def sum = 0
for (i in 0..3){
sum+=i
}
//println sum
sum = 0
//对list循环
for(i in [1,2,3,4,5,6]){
sum+=i
}
//println sum
sum = 0
//对map的循环
for(i in ['a':1,'b':2,'c':10]){
sum += i.value
}
println sum
四、闭包
groovy重大特性之一。闭包是一段代码块
4.1 闭包基础讲解
闭包的调用
def closer = {println 'hello world'}
//调用方式一
closer.call()
//调用方式二
closer()
闭包参数
//增加闭包参数
def closer2 = {String name -> println "hello ${name}"}
closer2("groovy")
//多个参数闭包
def intro = {String name,int age -> println "${name} is $age years old"}
intro.call("zhangsan",18)
//隐士默认参数it
def closer3 = {println "hello world,$it"}
closer3("哈哈")
闭包返回类值
//返回值 闭包一定会有返回值
def result = closer3()
println result
def closer4 = {return "hello world,$it"}
result = closer4("哈哈")
println result
4.2闭包的使用
与基本类型的使用
//求number的阶乘
int fab(int number){
int result = 1
1.upto(number, { result *= it })
return result
}
println fab(5)
int fab2(int number){
def result = 1
number.downto(1){
num-> result *= num
}
return result
}
println fab2(5)
int calcu(int number){
int sum = 0
number.times {
sum+=it
}
return sum
}
println calcu(4+1)
与字符串的使用
//字符串的闭包使用
def str = "hello world 119, groovy"
//hheelllloo wwoorrlldd ,, ggrroooovvyy 每个字符打印两次
str.each { print it*2}
println ""
//1
println str.find(){
it.isNumber()
}
//[1, 1, 9]
println str.findAll(){
it.isNumber()
}.toListString()
//any (存在一个)
def result = str.any {
String tmp -> tmp.isNumber()
}
println(result)
println str.every {
it.isNumber()
}
//collect方法 和js的map相似
println str.collect(){
it.toUpperCase()
}
4.3 闭包进阶
闭包的三个重要变量
this owner delegate
打印一下这三个变量
def scriptCloser = {
println "scriptCloser this: " + this //代表闭包定义处的类
println "scriptCloser owner: " + owner //代表闭包定义处的类或者对象 (因为闭包是可以嵌套的)
println "scriptCloser delegate: " + delegate //代表任意对象,默认是owner一致
}
scriptCloser.call()
class Person{
def static classCloser = {
println "classCloser this: " + this //代表闭包定义处的类
println "classCloser owner: " + owner //代表闭包定义处的类或者对象 (因为闭包是可以嵌套的)
println "classCloser delegate: " + delegate //代表任意对象,默认是owner一致
}
def static say(){
def classCloser = {
println "methodCloser this: " + this //代表闭包定义处的类
println "methodCloser owner: " + owner //代表闭包定义处的类或者对象 (因为闭包是可以嵌套的)
println "methodCloser delegate: " + delegate //代表任意对象,默认是owner一致
}
classCloser.call()
}
}
Person.classCloser.call()
Person.say()
println "-----------------------------------------------"
//在闭包中定义闭包
def outerCloser = {
def innerCloser = {
println "innerCloser this: " + this //代表闭包定义处的类
println "innerCloser owner: " + owner //代表闭包定义处的类或者对象 (因为闭包是可以嵌套的)
println "innerCloser delegate: " + delegate //代表任意对象,默认是owner一致
}
innerCloser.call()
}
outerCloser.call()
println "-----------------------------------------------"
//在闭包中定义闭包
def outerCloser2 = {
def innerCloser = {
println "innerCloser this: " + this //代表闭包定义处的类
println "innerCloser owner: " + owner //代表闭包定义处的类或者对象 (因为闭包是可以嵌套的)
println "innerCloser delegate: " + delegate //代表任意对象,默认是owner一致
}
//修改delegate
innerCloser.delegate = new Person()
innerCloser.call()
}
outerCloser2.call()
在闭包嵌套闭包中,内部闭包的owner和delegate默认指向外层闭包的。虽然owner和this不能改变,但是我们可以修改闭包的delegate,从而修改闭包的执行策略
class Java{
def name = "Java"
//定义一个闭包
def printCloser = {
println "this is $name"
}
//定义一个方法来调用闭包
String toString(){
printCloser.call()
}
}
class Android{
def name = "Android"
}
def java = new Java()
def android = new Android()
java.toString()
//修改闭包策略
java.printCloser.delegate = android
java.printCloser.resolveStrategy = Closure.DELEGATE_ONLY
java.toString()
五、数据结构
- 列表
- 映射
- 范围
5.1 列表
5.1.1 列表与数组的定义
def list = new ArrayList() //定义java list
def list1 = [1,2,3,4]
println list1.class
//定义数组
def array = [1,2,3,4,5] as int[]
int[] array2 = [1,2,3,4]
println array.class
println array2.class
5.1.2 列表操作
//排序 Collections.sort
//对基本数据类型的排序
def money = [1,-9,7,6,4,5,-3,5,-11]
//java工具
Collections.sort(money)
//默认从小到大排序
money.sort()
//根据绝对值排序
money.sort{Math.abs(it)}
//双参数闭包
money.sort{
a,b -> a==b?0:a>b?-1:1
}
//查找 find findAll any every min max count
println money.find { it % 2 == 0 }
println money.findAll { it % 2 != 0 }.toListString()
//
println money.any{Math.abs(it) == 11}
println money.every{Math.abs(it) < 8}
//获取数组中的最小值
println money.min()
//最大绝对值的元素
println money.max{Math.abs(it)}
//求数组整数的个数
println money.count { it > 0 }
5.2 映射
5.2.1 定义
def map = new HashMap()
def colors = ['red':'f00','green':'0f0','blude':'00f']
print colors['red']
print colors.red
//添加元素
colors.yellow = 'ffff00'
println colors.toMapString()
colors.complex = [a:1,b:2]
定义注意 ,key 要用单引号字符串
获取类型,要用getClass,不能直接.class
5.2.3 使用
def students = [
1:[number:'001',name:'zhangsan',score:19],
2:[number:'002',name:'lisi',score:29],
3:[number:'003',name:'wangwu',score:69],
4:[number:'004',name:'zhaoliu',score:99],
]
//遍历
students.each {
println "key : $it.key , value: $it.value"
}
println "----------------------------------"
students.eachWithIndex { def studnt, int index -> println "index $index , key : $studnt.key , value: $studnt.value" }
println "----------------------------------"
//解构方式
students.each{ key, value -> println "key : $key , value: $value"}
println students.find { it.value.score > 60 }.value.name
println students.findAll { it.value.score > 20 }.collect { it.value.name }
//分组,返回的是一个map,其中key为分组名称
println students.groupBy {
def student -> student.value.score <60?"needhard":"good"
}.toMapString()
println "----------------------------------"
//排序
students.sort { def stu1, def stu2 -> stu1.value.score == stu2.value.score ? 0 : stu1.value.score > stu2.value.score ? -1 : 1 }
.collect {[name:it.value.name,score:it.value.score]}
.each {
println "name: $it.name , score : $it.score"
5.3 范围
范围是继承与list
def r = 1..10
println r[0]
println r.from
println r.to
r.each {
println(it)
}
//能写循环的地方,看看能不能使用闭包
for (i in r){
println i
}
def result = getGrade(99)
println result
def getGrade(Number numer){
def result
switch (numer){
case 0..<60:
result = "不及格"
break
case 60..<90:
result = "及格"
break
case 90..<100:
result = "优秀"
break
}
return result
}
六、面向对象
6.1 定义类
/**
* Groovy中默认都是public
*/
class Person{
String name
Integer age
def increaseAge(Integer years){
this.age +=years
}
}
/**
* 无论是.属性还是调用getter都是调用的getter
*/
def person = new Person(name: "zhangsan", age: 10)
println "the name is ${person.name} , the age is ${person.age}"
/**
* 接口中不允许定义非public的方法
*/
interface Action {
void eat()
void drink()
void play()
}
/**
* 可以有抽象方法和默认实现
*/
trait defaultAction {
abstract void eat()
void play(){
println "I am playing"
}
}
6.2 元编程
上面groovy是运行时
def person = new Person(name: "zhangsan", age: 10)
person.cry()
Caught: groovy.lang.MissingMethodException: No signature of method: orientobject.Person.cry() is applicable for argument types: () values: []
Possible solutions: any(), any(groovy.lang.Closure), eat(), play(), grep(), every()
groovy.lang.MissingMethodException: No signature of method: orientobject.Person.cry() is applicable for argument types: () values: []
Possible solutions: any(), any(groovy.lang.Closure), eat(), play(), grep(), every()
at orientobject.objectstudy.run(objectstudy.groovy:9)
根据上述图中,重新invokeMethod可以避免异常抛出
class Person{
...
...
@Override
Object invokeMethod(String name, Object args) {
println "the method name is $name ,the args is $args"
}
}
当然也可以扩展person类的metaClass实现
//为类动态增加一个属性
Person.metaClass.sex = 'male'
def person2 = new Person(name: "lisi", age: 10)
person2.sex = 'nv'
println person2.sex
println '-------------------------------'
//为类动态增加方法
Person.metaClass.hello = {print 'hello'}
def person3 = new Person(name: "lis3", age: 10)
person3.hello()
//扩展静态方法
Person.metaClass.static.createPersion = { String name, Integer age -> new Person(name: name, age: age) }
def p = Person.createPersion("zfc", 28)
println p.name
上面扩展的成员都是临时的,只在当前文件有效。如果想要设置为全局,需要按照如下方式:
class PersonManager {
static createPerson(String name,int age){
return Person.createPerson(name,age)
}
}
class ApplicationManager {
static void init(){
//注意,要想实现全局扩展成员,需要
//调用 ExpandoMetaClass.enableGlobally()
ExpandoMetaClass.enableGlobally()
Person.metaClass.static.createPerson = { String name, int age ->
return new Person(name:'zhangsi',age:19)
}
}
}
class Entry {
static void main(def args) {
ApplicationManager.init()
println "应用启动中..."
def person = PersonManager.createPerson('zhangsi',19)
println "name is ${person.name} ,age is ${person.age}"
}
}