gradle构建脚本的语言是groovy,它的特点是全面兼容java,同时也有自身比较有特色的语法及api,这里我只是简单例举一些我自己玩过的比较有特点的groovy一些写法和api,基本上在gradle中参与度比较高的核心语法和api都有涉及到。当然详细的内容还是看官方文档比较全面。
Apache Groovy官方文档
W3Cschool groovy教程
一、变量
强类型(要给其他模块、其他类使用)
int x = 10
弱类型(自己类内部使用):类似于var
def y = 11
二、字符串
' ' 单引号 不可变常量字符表示
“ " 双引号 可拓展字符串 //def str = "this is a ${variable}"
""" """ 三引号字符串能保持格式
核心api:这里重点学习StringGroovyMethods 它又继承于DefaultGroovyMethods。
def str = “groovy”
//字符串获取
str.getAt(0)
str.getAt(0) //get操作
str[0]//类似数组操作
str[0..1] // [0,1]//范围操作
//常用api
each 变量
find查询第一个符合条件的值
findAll 找到所有符合条件值
any 只要有一项符合条件就返回true
every 每一项都符合条件才返回true
isNumber 是否是数字类型字符串
capitalize 字符串首字母大写
reverse 字符串倒序
minus 字符串删除部分字符串
等
这些方法可以结合闭包使用,增加业务逻辑判断。
例如:
//查找第一个为数字的字符
str.find{
String s -> s.isNumber()
}
字符串比较可以使用java的方式。
三、 逻辑控制
if else没差别。
switch case比java强大,case可以是任意类型的对象
def dest = 1.23
def result
switch (dest) {
case 'foo':
result2 = 'found foo'
break
case [4, 5, 6]:
result = 'list'
break
case 12..30:
result = 'range'
break
case Integer:
result = “integer"
break
case BigDecimal:
result = 'big decimal'
break
default: result = 'default'
}
for循环写法更简洁
//对范围的for循环
def sum = 0
for (i in 0..9) {
sum += i
}
//对list的循环
for (i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) {
sum += i
}
//对map的循环
for (i in ["zhangsan": 1, "lisi": 2, "wangwu": 3]) {
sum += i.value
}
四、 数据结构
list
def list1 = new ArrayList()//java 定义方式
def list = [1, 2, 3, 4, 5] //list初始化默认是arrayList
//or def list1 = [] 定义一个空集合
def array = [1, 2, 3] as int[] //通过as来转为数组或者其他类型集合
int[] arr = [1, 2, 3, 4] //数组
//列表元素添加
list.add(6)
list.leftShift(7) //也是添加
list << 8
def plusList = list + 9
println plusList.toListString()
//列表元素删除
list.remove(0) //删除index为0的元素
list.remove((Object) 7) //删除值为7的元素
list.removeAll { return it % 2 == 0 } //结合闭包做条件删除
println list
//列表排序
def sortList = [6, 0, 2, 3]
Comparator mc = { a, b -> a == b ? 0 : Math.abs(a) < Math.abs(b) ? -1 : 1 }
Collections.sort(sortList,mc) //使用Collections.sort排序,可以添加比较条件
//sortList.sort() 用集合自身sort方法
sortList.sort {
a, b -> a == b ? 0 : Math.abs(a) < Math.abs(b) ? 1 : -1
}
println sortList
def sortStringList = ['abc', 'z', 'hello']
println sortStringList.sort { return it.size() }//可用闭包做排序条件
//列表查找
def findList = [-3, 9, 2, 4, 1]
println findList.findAll { return it % 2 == 0 }
println findList.any { return it % 2 == 0 }
println findList.every { return it % 2 == 0 }
println findList.min { return Math.abs(it) }
println findList.max()
println findList.count { return it % 2 == 0 } //统计
//闭包指定规则非常实用
map
def map = new HashMap() //Java方式
//默认key为单引号字符串
def colorMap = [red: 'ff00000', green: '00ff00', blue: '0000ff'] //closure map
//get
println colorMap.get('red')
println colorMap['red’] //类似数组操作
println colorMap.red // .操作
//put
colorMap.put('yellow', 'ffff00')
colorMap.yellow = 'ffff00'
//最常用的是.操作符
//可以添加不同类型数据
colorMap.complex = [a: 1, b: 2]
println colorMap.toMapString()
//map默认LinkedHashMap 修改:可以通过as指定特定Map, 或者直接强类型指定Map类型
//删除
//colorMap.remove(key)
//colorMap.removeAll {}
//map操作详解
def students = [
1: [number: '0001', name: "zhangsan", score: 50],
2: [number: '0002', name: "lisi", score: 70],
3: [number: '0003', name: "wangwu", score: 60]
]
//遍历
students.each { def student ->
println "key is ${student.key}" +
"value is ${student.value}"
}
//遍历加入index下标
students.eachWithIndex { def student, int index ->
println "index is ${index}," +
"key is ${student.key}," +
"value is ${student.value}"
}
//直接遍历key-value
students.eachWithIndex { key, value, index ->
println "index is ${index}," +
"key is ${key}," +
"value is ${value}"
}
//查找
println students.find { def stu ->
return stu.value.score >= 60
}
println students.findAll { def stu ->
return stu.value.score >= 60
}
//count
//在闭包输出基础上再加个闭包条件 构造查找组合
println students.findAll { def stu ->
return stu.value.score >= 60
}.collect {
return it.value.name
}
//分组
def group = students.groupBy { def student ->
return student.value.score >= 60 ? "及格" : "不及格" //两个作为新的key
}
println group.toMapString()
//排序
println students.sort {
def stu1, stu2 ->
Number score1 = stu1.value.score
Number score2 = stu2.value.score
return score1 == score2 ? 0 : score1 < score2 ? -1 : 1
}
range
//range是list子类,属于轻量级list。这个概念kotlin也有
def range = 1..10 //定义
println range[0] //获取
println range.contains(10) //包含
println range.from + "," + range.to
//遍历也可以使用 each
range.each {
return it //推荐
}
五、闭包
闭包是groovy核心功能,需要重点掌握
//无参闭包
def clouser = {
println 'hello groovy'
}
//有参闭包
def clouser2 = {
String name -> println "hello ${name}"
}
clouser2("closure”)//调用 传参
//多参闭包
def clouser3 = {
String name, int age -> println "hello ${name},age is ${age}"
}
clouser3("zhangsan", 20)
//默认参数 it
def clouser4 = {
println "hello ${it}"
}
clouser4("world!”)
//两种调用方式
clouser.call() //推荐 比较直观一点
clouser()
闭包本身是用来做业务逻辑的语句块,可以作为一种参数(Closure closure)传入方法:
例如:
def str = ‘hello'
//find查询第一个符合条件的值
str.find{
String s -> s.isNumber()
}
闭包三个重要变量:
this 代表闭包定义处的类
owner 代表闭包定义处的类或者对象
delegate 代表任意对象,默认与owner一致
闭包可以定义在类、方法、闭包中。
this 、owner 、delegate 在类中闭包、方法中闭包是一致的,闭包中的闭包有区别,其中owner、delegate指向最近的闭包对象,
人为的修改了delegate,那么会跟owner不一样。另外this owner闭包定义了就不能修改,delegate可以任意修改。
闭包委托策略
class Student{
String name
def pretty = {"my name is ${name}”}
String toString(){
pretty.call()
}
}
class Teacher{
String name
}
def student = new Student(name:"jack")
def teacher = new Teacher(name:"sara")
student.pretty.delegate = teacher //修改delegate
//同时修改委托策, 默认是OWNER_FIRST
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST //先去delegate找,找不到再去owner找
println student.toString()
打印:my name is sara
六、面向对象
//类
class People {
String name
Integer age
def increateAge(Integer years) {
this.age += years
}
}
def p = new People(name: 'stan', age: 20)//创建实体对象,并且赋值
println "this name is ${p.name},age is ${p.age}" //.name 等价于getName()
p.increateAge(10)
//接口
interface Action {
void eat()
void drink()
}
//接口实现
class ActionImpl implements Action {
@Override
void eat() {
}
@Override
void drink() {
}
}
//trait : 接口方法有默认实现 类似于接口适配模式
trait Action1 {
abstract void eat()
abstract void drink() //不做实现的需要加abstract关键字
void play() { //可以实现
}
}
class Action1Impl implements Action2{
@Override
void eat() {
}
@Override
void drink() {
}
}
七、元编程
runtime 运行期能力
class People {
String name
Integer age
def increateAge(Integer years) {
this.age += years
}
//methodMissing优先级高于invokeMethod
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}"
}
}
八、metaClass 为类动态添加属性或者方法
//为类动态添加一个属性
People1.metaClass.sex = 'male'
//为类动态添加一个方法
People1.metaClass.sexUpperCase = {
-> sex.toUpperCase()
}
//为类动态添加静态方法
People1.metaClass.static.createPerson = {
String name, int age -> new People1(name: name, age: age)
}
def p2 = new People1(name: 'zs', age: 31)
println p2.sex
println p2.sexUpperCase()
def person3 = People1.createPerson('zht', 31)
println person3.name + "," + person3.age
//metaClass 使用场景:例如final class 属性和方法的拓展
九、文件操作
文件操作
def file = new File('../helloGroovy.iml')
//groovy 逐行读取文件
file.eachLine { line ->
println line
}
//or
// groovy 一次获取所有文本
def text = file.getText()
//or
def list = file.readLines()
//读取文件部分内容
file.withReader { reader ->
char[] buffer = new char[100]
reader.read(buffer)
return buffer
}
//copy功能
def copy(String sourcePath, String desPath) {
try {
def desFile = new File(desPath)
if (!desFile.exists()) {
desFile.createNewFile();
}
//读取源文件内容
new File(sourcePath).withReader { reader ->
def lines = reader.readLines()
desFile.withWriter { writer ->
lines.each { line ->
writer.append(line + "\r\n")
}
}
}
return true
} catch (Exception e) {
}
}
println copy('../helloGroovy.iml', '../helloGroovy2.iml')
def saveObject(Object object, String path) {
try {
def desFile = new File(path)
if (!desFile.exists()) {
desFile.createNewFile();
}
desFile.withObjectOutputStream { out ->
out.writeObject(object)
}
return true
} catch (Exception e) {
}
return false
}
def readObject(String path){
def obj = null
try {
def file = new File(path)
if(file == null || !file.exists())
return null
file.withObjectInputStream { input ->
obj = input.readObject()
}
return true
} catch (Exception e) {
}
return false
}
json文件操作
def list = [new People1(name: "stan", age: 31),
new People1(name: "jack", age: 30)
]
//实体对象转json
def json = JsonOutput.toJson(list)
//打印出带格式的json
println JsonOutput.prettyPrint(json)
//json转实体对象
def jsonSlurper = new JsonSlurper()
def resultList = jsonSlurper.parse(json.getBytes())
println resultList.collect()
//也可以使用Gson
//新建libs目录,添加Gson jar包,add library 就可以使用。使用与java写法一样
//一个获取网络请求再将json转为实体的小实例
def getNetworkData(String url) {
//发送http请求
def connection = new URL(url).openConnection()
connection.setRequestMethod('GET')
connection.connect()
def response = connection.content.text
//将json转化为实体对象
def jsonSlu = new JsonSlurper()
return jsonSlu.parseText(response)
}
def resp = getNetworkData(‘XXXX')
println resp
xml文件操作
//groovy如何解析一个xml格式数据
final String xml = """
<response version-api="2.0">
<value>
<books id="1" classification="novel">
<book available="20" id="1">
<title>百年孤独</title>
<author id="1">马尔克斯</author>
</book >
<book available="14" id="2">
<title>三体</title>
<author id="2">刘慈欣</author>
</book >
</books>
<books id="2" classification="android">
<book available="30" id="3">
<title>第一行代码</title>
<author id="3">郭林</author>
</book >
<book available="18" id="4">
<title>疯狂Android讲义</title>
<author id="4">李刚</author>
</book >
<book available="32" id="5">
<title>第二行代码</title>
<author id="5">郭林</author>
</book >
</books>
</value>
</response>
"""
//xml解析
def xmlSlurper = new XmlSlurper()
def result = xmlSlurper.parseText(xml)
println result.value.books[0].book[0].title.text() //获取节点值
println result.value.books[1].book[0].@available //获取节点属性
//遍历所有郭林的书
def lists = []
result.value.books.each { books -> //这里省略了def
//对书节点进行遍历
books.book.each { book ->
def author = book.author.text()
if (author.equals('郭林')) {
lists.add(book.title.text())
}
}
}
println lists.toListString()
//深度遍历
println result.depthFirst().findAll { book ->
if (book.author.text() == '郭林' ? true : false) {
return book.title.text()
}
}
//广度遍历
println result.value.books.children().findAll { node ->
node.name() == 'book' && node.@id == '2'
}.collect { node ->
return node.title.text()
}
//groovy如何创建一个xml格式数据
/**
* 静态写法
* <langs type='current' count='3' mainstream='true'>
<language flavor='static' version='1.5'>java</language>
<language flavor='dynamic' version='1.6'>groovy</language>
</langs>
*/
def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)//生成xml数据的核心类
//创建根节点
xmlBuilder.langs(type: 'current', count: '3', mainstream: 'true') {
//子节点
language(flavor: "static", version: '1.5', 'java') //language下再想要子节点,那对language做闭包就好 { }
language(flavor: "dynamic", version: '1.6', 'groovy')
}
println sw
/**
* 实体类转为xml
*/
class Langs {
String type = 'current'
int count = 3
boolean mainstream = true
def languages = [new Language(flavor: "static", version: '1.5', value: 'java'),
new Language(flavor: "dynamic", version: '1.6', value: 'groovy'),]
}
class Language {
String flavor
String version
String value
}
def langs = new Langs()
println xmlBuilder.langs(type: langs.type, count: langs.count, mainstream: langs.mainstream) {
langs.languages.each { lang ->
language(flavor: lang.flavor, version: lang.version, lang.value)
}
}
println sw











网友评论