1. 变量的类型 1.int double 等基本类型 2. 对象类型--> 最终都是对象类型
package variable
int x = 10
println x.class
double y = 3.14
println y.class
输出:
class java.lang.Integer
class java.lang.Double
Process finished with exit code 0
2. 变量的定义
1. 强类型定义 2. 弱类型定义(def 定义)
强类型定义就是指明了具体的数据类型,而弱类型定义就是不指明数据类型,而是通过数据推断出来具体的数据类型。
def x_1 = 11
println x_1.class
def y_1 = 3.14
def name = 'android'
x_1 = 'iOS'
println x_1.class
println y_1.class
println name.class
输出:
class java.lang.Integer
class java.lang.String
class java.math.BigDecimal
class java.lang.String
从上面可以看出,def定义的变量是可以随意改变数据类型的。
注意:如果是自己用就可以用 def,如果是用于提供给其他模块使用,则需要强类型的定义。
1. 字符串有两种定义方式 String 和 GString 这两种类型,GString 可扩展字符串 ${name}
name = 'android'
//x_1 = 'iOS'
//println x_1.class
//println y_1.class
//println name.class
//1. 单引号字符串和Java中双引号字符串
def name = 'a single string'
println name.class
def thupleName = '''\
line one
line two
line three
'''
println thupleName
println thupleName.class
//单引号 和 三引号 定义的字符串的区别
//三个单引号可以直接指定格式
//如果是单引号则需要拼接和转移字符才能实现该功能
def doubleName = "this a common String"
println doubleName.class
//双引号与其他有什么区别
//可扩展字符串
//有了扩展表达式 ${变量名},则就是可扩展字符串
def name_android = "Qndroid"
def sayHello = "hello: ${name_android}"
println sayHello
//class org.codehaus.groovy.runtime.GStringImpl
println sayHello.class
//可扩展可以做任意的表达式
def sum = "The sum of 2 and 3 equals ${2+3}"
println sum
def result = echo(sum)
//结果表明String类型和GString是可以相互转化的
println result
println result.class
String echo(String message){
return message
}
2. 新增操作符
///字符串的方法
//1. java.lang.String 来源
//2. DefaultGroovyMethods
//3. StringGroovyMethods 1. 普通类型的参数 2. 闭包类型的参数
//普通类型参数
def str = "Hello groovy"
//center左右字符串的填充 agroovya
println str.center(8, 'a')
//添加已有字符串的左边 aagroovy
println str.padLeft(8, 'a')
//方法比较
def str2 = 'Hello'
//1. 方法比较
//println str.compareTo(str2)
//2. 操作符比较
println str > str2
//获取指定位置字符
println str.getAt(0)
println str[0]
//输出的是gr,左右是闭区间
println str[0..1]
//str中减去str2字符串
println str.minus(str2)
//倒序输出
println str2.reverse()
//首字母大写
println str.capitalize()
//判断是否是数字类型
println str.isNumber()
3. 逻辑控制
//Groovy中的switch比Java中更强大
//Java中只能指定一种类型,不会匹配到多种类型
def x = 1.23
def result
switch (x.class) { //可以解决 instanceof if else这种 直接进行类型判断
case 'foo':
resutl = 'found foo'
break
case 'bar':
result = 'found bar'
break
case [4,5,6, 'inlist']://列表
result = 'list'
break
case 12..30:
result = 'range'//范围
break
case Integer:
result = 'integer'
break
case BigDecimal:
result = 'bigDecimal'
break
default:
result='default'
}
println result
//对范围的for循环
def sum = 0
for (i in 0..9){
sum +=i
}
//println sum
sum = 0
//对List的循环
for (i in [1,2,3,4,5,6,7,8,9]){
sum+=i
}
//对Map的循环
for (i in ['lili':1, 'lucy':2,'xiaoming':3]){
sum+=i.value
}
1. Groovy闭包的概念 2. Groovy闭包的使用详解
Groovy中闭包比其他语言中的闭包更加强大
闭包概念:
1. 闭包就是一个代码块,和方法差不多 2. 闭包的调用,使用call或者方法的调用方法进行调用
package variable
def closure = { // 这样已经算作是一个闭包
println 'Hello groovy'
}
closure.call()
//注意和方法的调用比较
closure()
//输出
Hello groovy
Hello groovy
2. 闭包参数 闭包如何传递参数
def closure = { String name, int age ->
println "Hello ${name}, My age is ${age}"
}
def name = 'groovy'
closure.call('groovy',10)
closure(name,4 )
//输出
Hello groovy, My age is 10
Hello groovy, My age is 4
3. 闭包只有一个传入参数,可以省略参数列表,该参数使用 it 代替
def closurer = {
println "Hello ${it}" // it 是默认的参数,只有一个参数的使用
}
closurer("ShangHai")
//输出
Hello ShangHai
4. 闭包返回值 闭包一定有返回值,默认是闭包的最后一行
//闭包返回值 闭包一定有返回值
def returnClosure = { String na->
//return "Hello ${na}" //有返回值
"Hello ${na}" //也有返回值
}
def result = returnClosure("BeiJing")
println result
//输出
Hello BeiJing
注意:插件也是用的Groovy语言开发的
5. 闭包结合方法使用
//闭包的使用
//用指定方法来求阶乘
int x = fab(5)
println x
int y = fab2(5)
println y
int z = cal(101)
println z
//upto
int fab(int number){
int result = 1
1.upto(number, {num -> result*=num})
return result
}
//downto
int fab2(int number){
int result = 1
number.downto(1){
num -> result*=num
}
return result
}
//累加
int cal(int number){
int result
number.times {
num -> result+= num
}
return result
}
6. 闭包和字符串结合使用
//字符串与闭包的结合使用
String str = 'the 2 and 3 is 5'
//each遍历
//如果闭包在方法参数的最后位置,则可以将闭包放在方法括号外部
//each返回值是str本身
str.each {
//输出字符串中的每个字符
String temp -> println temp
}
//find来查找符合条件的第一个字符
//输出打印 2
println str.find {
String s -> s.isNumber()
}
//查找所有符合条件的对象并返回集合
//输出打印[2, 3, 5]
def list = str.findAll {
String s -> s.isNumber()
}
//[2, 3, 5]
println list.toListString()
//只要符合条件就返回true 否则返回false
def result = str.any {
String s -> s.isNumber()
}
println result
//判断是否每一项都符合条件,如果都符合条件返回true,否则返回false
def result2 = str.every {
String s -> s.isNumber()
}
println result2
//所有经过闭包变换处理的对象都放在一个新的集合中
def list2 = str.collect {
it -> it.toUpperCase()
}
//[T, H, E, , 2, , A, N, D, , 3, , I, S, , 5]
println list2.toListString()
7. 闭包进阶
闭包进阶的三个变量 this,owner,delegate
//1. 闭包的三个关键变量 this owner delegate 闭包强大的核心
def scriptClosure = {
println "scriptClosure this: "+this //this 代表闭包定义处的类
println "scriptClosure owner: "+owner //代表闭包定义处的类或者对象
println "scriptClosure delegate: "+delegate //代表任意对象,有默认值为owner
}
scriptClosure.call()
//输出
scriptClosure this: variable.closure03@531f4093
scriptClosure owner: variable.closure03@531f4093
scriptClosure delegate: variable.closure03@531f4093
this,owner,delegate 三种变量的区别
//相当于定义个了一个内部类,其外部类是closure03
class Person {
//def static classClosure = {
def classClosure = {
println "classClosure this: "+this //this 代表闭包定义处的类
println "classClosure owner: "+owner //代表闭包定义处的类或者对象
println "classClosure delegate: "+delegate //代表任意对象,有默认值为owner
}
def say(){
def classClosure = {
println "methodClassClosure this: "+this //this 代表闭包定义处的类
println "methodClassClosure owner: "+owner //代表闭包定义处的类或者对象
println "methodClassClosure delegate: "+delegate //代表任意对象,有默认值为owner
}
classClosure.call()
}
}
Person p = new Person()
p.classClosure.call()
p.say()
//在闭包中定义一个闭包,看this和owner是否还是有区别?
def nestClosure = {
def innerClosure = {
println "innerClosure this: "+this //this 代表闭包定义处的类,指向closure03这个类??
println "innerClosure owner: "+owner //代表闭包定义处的类或者对象 可以指向闭包对象 指向nestClosure ?
println "innerClosure delegate: "+delegate //代表任意对象,有默认值为owner
}
innerClosure.delegate = p //修改默认的delegate对象,如果不修改,则delegate和owner指向的都是同一个对象
innerClosure.call()
}
nestClosure.call()
//总结:如果是在类中定义闭包,则this, owner, delegate 是一样的
//但是如果在闭包中嵌套闭包,则this 和 owner, delegate 不一样,owner指向最近的闭包对象
//如果人为的修改闭包的delegate, 则delegate则和owner不一样
//this和owner是不能修改的
//输出
classClosure this: variable.Person@134d26af
classClosure owner: variable.Person@134d26af
classClosure delegate: variable.Person@134d26af
methodClassClosure this: variable.Person@134d26af
methodClassClosure owner: variable.Person@134d26af
methodClassClosure delegate: variable.Person@134d26af
innerClosure this: variable.closure03@6187d1f5
innerClosure owner: variable.closure03$_run_closure1@17aad511
innerClosure delegate: variable.Person@134d26af
闭包委托策略
//2. 闭包委托策略
//闭包的this, owner,delegate 的作用是什么?
class Student {
String name
int age = 10
def pretty = {
//此处的name是指向定义闭包处的类(Student类)的name
"My name is ${name} age is ${age}"
}
String toString() {
pretty.call()
}
}
class Teacher {
String name
}
def stu = new Student(name: 'Sarah')
def tea = new Teacher(name: 'Jack')
println stu.toString()
stu.pretty.delegate = tea
//stu.pretty.resolveStrategy = Closure.OWNER_FIRST //代理策略 Owner优先
//stu.pretty.resolveStrategy = Closure.OWNER_FIRST
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST //代理策略 代理优先
//stu.pretty.resolveStrategy = Closure.DELEGATE_ONLY //代理策略 只有代理
println stu.toString()
//如何在不修改stu的name的情况下将输出名称修改为老师的名称?
//代理以及策略是在写框架的时候会用到,其他情况下很少用
//输出
My name is Sarah age is 10
My name is Jack age is 10
注意理解相关的概念和使用方法,也就是其中的技巧。
1. 列表的定义
//def list = new ArrayList() //Java中的定义方式
def list = [1,2,3,4,5]
println list.class //class java.util.ArrayList
println list.size() //5
def array = [1, 2, 3, 4, 5,] as int[] // int[] 数组
int[] array2 = [1, 2, 3, 4, 5] //数组
2. 列表添加元素
//方法一:列表的添加元素
list.add(6)
println list.toListString() //1 2 3 4 5 6
//方法二:列表添加元素
list.leftShift(7)
//方法三:列表添加元素
list<<8
println list.toListString()
//方法四:列表添加元素
def plusList = list + 9;
println plusList
3. 列表删除元素
//list的删除操作
list.remove(7)
println list.toListString()
//移除最后一个元素
list.removeLast()
println list.toListString()
//移除符合条件的元素,比如被2整除 [1, 3, 5]
list.removeIf{it -> it%2==0 }
println list.toListString()
4. 列表排序
//列表排序
def sortList = [6, -3, 9, 2, -7, 10]
//按照绝对值的大小进行排序
//Comparator mc = {a, b -> a==b ? 0: Math.abs(a)< Math.abs(b)? -1: 1}
//Collections.sort(sortList, mc)
sortList.sort{ a, b -> Math.abs(a)< Math.abs(b)? 1: -1}
println sortList
//按照某种规则进行指定规则排序
def sortStringList = ['a', 'bc','hello','kotlin', 'groovy', 'java']
sortStringList.sort{it-> it.size()}
println sortStringList
5. 列表查找元素
//列表中的查找
def findList = [-3, 9, 6, 2, 7, 1, 5]
//查找第一个符合条件的元素
int result = findList.find { return it%2==0 }
println result
//查找所有符合条件的元素
def resultList = findList.findAll {return it%2==0}
//[6, 2]
println resultList.toListString()
//查找是否有元素是否不能被2整除
def resultAny = findList.any {return it%2!=0}
println resultAny
//是否所有的元素都能整除2
def resultEvery = findList.every { return it%2==0}
println resultEvery
6. 列表中查找最大最小值
//查找列表中的最小值
def min = findList.min()
println min
//查找列表中对最大值
def max = findList.max()
println max
//按照规则选中最小的值
def minNew = findList.min { return Math.abs(it)}
println minNew
7. 统计列表中符合条件的元素个数
//count 用于统计符合规则的元素个数
def num = findList.count { return it%2== 0}
println num
8. Groovy中的映射
//groovy中的映射
def map = new HashMap()
def colors = [red:'ff0000', green:'00ff00', blue: '0000ff']
def red = colors['red']
println red
println colors.red
9. Map映射添加元素
//添加元素 比较常用
colors.yellow = 'ffff00'
//同样是添加元素,put方法不常用
colors.put('purple', 'ff00ff')
println colors.toMapString()
colors.complex = [a: 1, b:2]
println colors.toMapString()
//class java.util.LinkedHashMap
println colors.getClass()
10. Map的遍历
def students = [
1:[number:'0001', name:'bob', score: 55, sex: 'male'],
2:[number:'0002', name:'Johnny', score: 60, sex: 'female'],
3:[number:'0003', name:'Clarie', score: 67, sex: 'female'],
4:[number:'0004', name:'Amy', score: 80, sex: 'male'],
]
遍历
students.each {
def student ->
println "the key is ${student.key}, the value is ${student.value}"
}
students.eachWithIndex{ def student, int index ->
println "index is $index the key is ${student.key}, the value is ${student.value}"
}
students.each { key, value ->
println "the key is ${key}, the value is ${value}"
}
11. Map 映射查找
//Map的查找
def entry = students.find {
def student -> return student.value.score >= 60
}
println entry
def entrys = students.findAll {
def student -> return student.value.score>60
}
println entrys
def count = students.count {
def student -> return student.value.score>=60 && student.value.sex=='male'
}
println count
//查找所有及格的学生
def names = students.findAll {
def student -> return student.value.score>=60
}.collect {//重新构造一个列表
return it.value.name
}
//打印输出一个列表
println names.toListString()
12. Map 映射分组
//分组 按照某个标签分组
def groups = students.groupBy {
def student -> return student.value.score>=60?"及格":"不及格"
}
//[不及格:[1:[number:0001, name:bob, score:55, sex:male]],
//及格:[2:[number:0002, name:Johnny, score:60, sex:female],
//3:[number:0003, name:Clarie, score:67, sex:female], 4:[number:0004, name:Amy, score:80, sex:male]]]
println groups.toMapString()
13. Map的排序
//排序
def sort = students.sort {
def student1, def student2 ->
Number score1 = student1.value.score
Number score2 = student2.value.score
//从大到小排序
return score1 == score2 ? 0: score1< score2? 1: -1
}
println sort.toMapString()
14. 范围的定义
def range = 1..10
println range[0] //1
println range.contains(10) //true
//range的起始值 有两个属性 from,to
println range.from
println range.to
15. 范围range的遍历
//遍历
range.each {
println it
}
for (i in range){
println i
}
16. 范围range在方法中的使用
def result = getGrade(78)
println result //良好
def getGrade(Number number){
def result
switch (number){
case 0..<60:
result = '不及格'
break
case 60..<70:
result = '及格'
break
case 70..<80:
result = '良好'
break
case 80..100:
result = '优秀'
break
}
return result
}
1. Groovy中类,接口等的定义和使用和Java一致
2. Groovy中的元编程Java中没有,这是Groovy比Java强大的地方
1. 接口定义
//Action.groovy
//groovy 中不允许创建非public类型的方法
interface Action {
void eat()
void drink()
void play()
}
2. 类定义
//Person.groovy
//1. groovy中默认的都是public类型的,都会省略public修饰符
class Person implements Action, Serializable{
String name
Integer age
def increaseAge(Integer years){
this.age += years
}
@Override
void eat() {
}
@Override
void drink() {
}
@Override
void play() {
}
//methodMissing如果和invokeMethod同时存在的情况下,会走methodMissing方法
def methodMissing(String name, Object args){
return "the method ${name} is missing"
}
//在对象调用一个方法在找不到的情况下,调用它代替,可以避免抛出异常
def invokeMethod(String name, Object args){
return "the method is ${name}, the params is ${args}"
}
}
其中 methodMissing 和 invokeMethod 方法是两个比较特殊的方法,可以在对象调用一个不存在的方法的时候避免抛出异常,并按照优先级调用两个方法中的其中一个。同时需要注意,groovy语法中默认都是public修饰的,不需要添加public 关键字。
//2. 无论你是直接. 还是调用get/set最终都是调用 get/set方法
def person = new Person(name: 'Lucky', age: 26)
println "the name is ${person.name}, the age is ${person.age}"
person.increaseAge(10)
println person.age
//因为在Person中定义了invokeMethod和MethodMissing方法,所以不会报错
println person.cry()
//又像接口 又像抽象类,实现是用implements
trait DefaultAction {
abstract void eat()
void play(){
println 'i can not play'
}
}
如上便是调用方法的过程,有好多分支判断,关于 invokeMethod 和 MethodMissing 前面已经介绍过了,而MetaClass是本节要介绍的元编程相关的内容。
1. MetaClass 非常强大,可以为类动态的添加属性和方法,如下:
//script.groovy
//methodClass强大
//为类动态的添加一个属性 sex属性
Person.metaClass.sex = 'male'
def personNew = new Person(name:'', age: 10)
println personNew.sex
personNew.sex = 'female'
println "the new sex is : ${personNew.sex}"
//为类动态的添加方法
Person.metaClass.sexUpperCase = {-> sex.toUpperCase()}
def person2 = new Person(name:'lisi', age: 10)
println person2.sexUpperCase()
//为类动态的添加静态方法 createPerson静态方法
Person.metaClass.static.createPerson = {
String name, int age-> new Person(name: name, age: age)}
def person3 = Person.createPerson('lisisi', 23)
println "the name is $person3.name and age is $person3.age"
感觉有点类似Kotlin和Flutter中的扩展方法,可以在不修改源码的情况下,动态添加方法。
2. 在不修改源码的情况下,为类添加方法
//ApplicationManager.groovy
package oop
class ApplicationManager {
static void init(){
ExpandoMetaClass.enableGlobally()
//为第三方类添加方法 解决无法修改源码的问题
Person.metaClass.static.createPerson = {String name, int age->
new Person(name:name, age: age)
}
String.metaClass.static.printlog = {String data ->
println data
}
String.metaClass.static.reversedata = {String data ->
return data.reverse()
}
}
}
package oop
class PersonManager {
static Person createPerson(String name, int age){
//利用动态添加的createPerson静态方法创建Person对象
return Person.createPerson(name, age)
}
}
package oop
class Entry {
//应用程序入口
static void main(def args){
println "应用程序正在启动..."
//初始化
ApplicationManager.init()
println '应用程序初始化完成...'
def person = PersonManager.createPerson('wangwu',10)
println "the person name is $person.name and age is $person.age"
def student = 'studentxx'
student.printlog("ddd")
def result = student.reversedata("hello")
println result
}
}
如上总结了groovy中的变量、类、列表、映射等常见的数据类型,也介绍了常见的API操作,比如字符串操作、列表操作等,另外还有闭包的概念、使用以及this、Owner、delegate 等关键字的使用场景介绍,最后介绍了元编程的概念和使用,使得类可以动态的扩展属性和方法。