语法基础——Groovy语法基础

变量

1、变量类型

groovy变量没有基本数据类型,只有引用类型,尽管定义的基本类型也会被转换成引用类型

int x = 10
println x.class //class java.lang.Integer
double y = 10.10
println y.class //class java.lang.Double

2、弱类型

groovy变量可以有强类型方式和弱类型方式,弱类型方式会自动转换成对应的引用类型

def z = 'name'
println z.class //class java.lang.String
def h = 1.34
println h.class //class java.math.BigDecimal

字符串

1、无格式定义的字符串

无格式定义的字符串指的是输出的时候,字符串不会带有原本输入的格式

def name = 'Hensen'

2、有格式定义的字符串

有格式定义的字符串指的是输出的时候,会按照原本定义的格式进行输出

def name = '''\
line one
line two
line three
'''

3、GString

groovy提供新的字符串类型GString,用双引号定义的字符串表示可拓展的字符串

def name = "Hensen"
def say = "${name} say : Hello groovy"
println say //Hensen say : Hello groovy
println say.class //class org.codehaus.groovy.runtime.GStringImpl

def sum = "${2 + 3}"
println sum //5

4、字符串Api

groovy的字符串提供了很多Api对字符串进行操作

def str = "groovy"
println str.center(10,'1') //11groovy11
println str.padLeft(10,'1') //1111groovy
println str.padRight(10,'1') //groovy1111

def str2 = "java"
println str > str2 //false
println str[0] //g
println str[0..2] //grp

def str3 = "a"
println str2 - str3 //jva
println str.reverse() //yvoorg
println str.capitalize() //Groovy
println str.isNumber() //false

def str4 = "2"
println str4.toLong() //2

逻辑控制

1、switch-case

groovy提供的switch语句可以判断类型的参数

def x = 5.2
def result
switch (x){
    case 'you':
        result = "you"
        break
    case [3,4,5,"list"]:
        result = "inList"
        break
    case 12..30:
        result = "12 to 30"
        break
    case Integer:
        result = "Integer Params"
        break
    case BigDecimal:
        result = "BigDecimal Params"
        break
    default:result="default result"
}
println result //BigDecimal Params

2、for

//遍历范围
def sum = 0
for(i in 0..9){
    sum += i
}
println sum //45

//遍历集合
def sum2 = 0
for (i in [0,1,2,3,4,5]){
    sum2 += i
}
println sum2 //15

//遍历Map
def sum3 = 0
for(i in ["one":1,"two":2,"three":3]){
    sum3 += i.value
}
println sum3 //6

闭包

1、闭包

//无参闭包
def method = {println "Hello groovy"}
//有参闭包
def method2 = {String name -> println "Hello ${name}"}
//默认参数闭包
def method3 = {println "Hello ${it}"}
//带返回值闭包
def method4 = {return "Hello ${it}"}

//闭包的调用
def name = "groovy"
method.call()
method2(name)

2、闭包函数

def result = fab(5)
def result2 = fab2(5)
def result3 = cal(5)
println result //120
println result2 //120
println result3 //11

int fab (int number){
    int result = 1
    1.upto(number,{ num -> result *= num }) //执行1-number的闭包
    return result 
}

int fab2 (int number){
    int result = 1
    number.downto(1,{ num -> result *= num }) //执行number-1的闭包
    return result
}

int cal (int number){
    int result = 1
    number.times { num -> result += num} //执行0-number的闭包
    return result
}

3、字符串闭包函数

def intro = "my name is Hensen,my age is 18"
//找到第一个符合条件的字符
println intro.find {
    String s -> s.isNumber() //1
}
//找到所有符合条件的字符
println intro.findAll {
    String s -> s.isNumber() //[1, 8]
}
//有一项字符符合即可
println intro.any {
    String s -> s.isNumber() //true
}
//所有字符必须符合条件
println intro.every {
    String s -> s.isNumber() //false
}
//将字符串转换成集合
println intro.collect {
    it.toUpperCase() //[M, Y,  , N, A, M, E,  , I, S,  , H, E, N, S, E, N, ,, M, Y,  , A, G, E,  , I, S,  , 1, 8]
}
//遍历所有字符
intro.each {
    print it.toUpperCase() //MY NAME IS HENSEN,MY AGE IS 18
}

4、闭包关键字

闭包的关键字分为下面三个

  • this:代表当前闭包定义处的类
  • owner:代表当前闭包定义处的类或者对象
  • delegate:代表任意对象,默认与owner一致

一、正常闭包

在这里的this、owner、delegate表示同一个对象,即outer

def outer = {
    println "outer this:" + this
    println "outer owner:" + owner
    println "outer delegate:" + delegate
}
outer.call()

//输出结果
outer this:Chapter4o4@f48007e
outer owner:Chapter4o4@f48007e
outer delegate:Chapter4o4@f48007e

二、嵌套闭包

在这里的this表示outer2、这里的owner、delegate表示inner

def outer2 = {
    def inner = {
        println "inner this:" + this
        println "inner owner:" + owner
        println "inner delegate:" + delegate
    }
    inner.call()
}
outer2.call()

//输出结果
inner this:Chapter4o4@f48007e
inner owner:Chapter4o4$_run_closure2@11cfefda
inner delegate:Chapter4o4$_run_closure2@11cfefda

三、委托策略

delegate关键字跟委托策略有关,委托策略有四种

  • DELEGATE_FIRST:先从Delegate去找委托属性,再从Owner去找委托属性
  • DELEGATE_ONLY:只从Delegate去找委托属性
  • OWNER_FIRST:先从Owner去找委托属性,再先从Delegate去找委托属性
  • OWNER_ONLY:只从Owner去找委托属性
class Student{
    String name
    def content = {"my name is ${name}"}
    String toString(){
        content.call()
    }
}

class Teacher{
    String name
}

def stu = new Student(name: "HensenStudent")
def tea = new Teacher(name: "HensenTeacher")
stu.content.delegate = tea
stu.content.resolveStrategy = Closure.DELEGATE_FIRST
println stu.toString()

//输出结果
my name is HensenTeacher

列表

1、定义

//定义列表
def list = [1,2,3,4]

//定义数组
def array = [1,2,3,4] as int[] 
int[] array = [1,2,3,4]

2、列表增操作

def list = [1,2,3,4]
list.add(5)
list << 6
println list.toListString()

def list2 = list + 7
println list2.toListString()

3、列表删操作

def list = [1,2,3,4]
list.remove(0)
list.remove((Object)4)
list.removeAt(0)
list.removeElement(4)
list.removeAll({return it % 2 == 0})
println list.toListString()

def list2 = list - [2,3]
println list2.toListString()

4、列表排操作

def list = [1,5,-4,8,6,2]
list.sort()
list.sort{a,b -> a == b ? 0 : Math.abs(a) > Math.abs(b) ? 1 : -1}
println list.toListString()

def strings = ['abc','2','qwe','apple','java']
strings.sort{it -> return it.size()}
println strings.toListString()

5、列表查操作

def list = [1,5,-4,8,6,2]
println list.find{ return it % 2 == 0 }
println list.findAll{ return it % 2 == 0 }
println list.any{ return it % 2 == 0 }
println list.every{ return it % 2 == 0 }
println list.min()
println list.max()
println list.count{ return it % 2 == 0 }

映射

1、定义

def colors = [red:'#ff0000',green:'#00ff00',blue:'#0000ff']
colors.yellow = '#ffff00' //默认找不到字段则为新增字段
colors.complex = [a:1,b:2]
println colors.blue
println colors.yellow

2、Map遍历操作

def map = [
        1:[name : 'Hensen',age : '20'],
        2:[name : 'Jack',age : '22']
]

map.each { def person ->
    println "the person name : ${person.key}" +
            "the person age : ${person.value}"
}

map.eachWithIndex{ def person, int index ->
    println "the index : ${index}" +
            "the person name : ${person.key}" +
            "the person age : ${person.value}"
}

map.eachWithIndex{ key , value, int index ->
    println "the index : ${index}" +
            "the person name : ${key}" +
            "the person age : ${value}"
}

3、Map查操作

println map.find { def person -> return person.value.age >= 20}
println map.findAll { def person -> return person.value.age >= 20}
println map.count { def person -> return person.value.age >= 20}
println map.findAll { def person -> return person.value.age >= 20}.collect { return it.value.name}
println map.groupBy { def person -> return person.value.age >= 22 ? "大于22岁" : "小于22岁"}
println map.sort { def person1, def person2 ->
    Number age1 = person1.value.age
    Number age2 = person2.value.age
    return age1 == age2 ? 0 : age1 > age2 ? 1 : -1
}

范围

1、定义

def range = 1..10
println range[0]
println range.contains(2)
println range.from
println range.to

2、循环

range.each{
    println it
}
for (i in range){
    println i
}

3、匹配

def getGrade(Number number){
    def result
    switch (number){
        case 0..<60:
            result = "不及格"
            break
        case 60..<90:
            result = "优秀"
            break
        case 90..100:
            result = "接近满分"
            break
    }
    return result
}

元编程

1、捕获未声明的方法

如果在调用对象的方法时,该方法未被声明的情况下

  1. 会被优先级高的methodMissing()捕获
  2. 其次会被优先级低的invokeMethod()捕获
  3. 如果这两个方法都未声明,则程序会报错
class Person{
    String name
    Integer age

    @Override
    Object invokeMethod(String s, Object arg) {
        return "[invokeMethod] the method is " + s + ", and the params is " + arg
    }

    def methodMissing(String s, Object arg){
        return "[methodMissing] the method is " + s + ", and the params is " + arg
    }
}

Person p = new Person(name: "Hensen",age: 22)
println p.say("Hello") //[methodMissing] the method is say, and the params is [Hello]

2、动态添加属性和方法

class Person{
    String name
    Integer age
}

//动态添加一个属性
Person.metaClass.sex = "male"
//动态添加方法
Person.metaClass.getUpperName = { -> name.toUpperCase() }
//动态添加静态方法
Person.metaClass.static.createPerson = { String name ,Integer age-> new Person(name: name,age: age) }

Person p = new Person(name: "Hensen",age: 22)
println p.sex
println p.getUpperName()
println Person.createPerson("Jack",20).name

3、为第三方类添加属性和方法

ExpandoMetaClass.enableGlobally()
String.metaClass.static.sayHello = { String str -> return "Hello" + str}
println String.sayHello("Hensen")

Json操作

1、对象转换成Json字符串

def list = [new Person(name: 'Hensen',age: 20),new Person(name: 'Jack',age: 22)]
def json = JsonOutput.toJson(list)
println json //[{"age":20,"name":"Hensen"},{"age":22,"name":"Jack"}]

2、Json字符串转换成对象

def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(json)
println object[0].name //Hensen

Xml操作

1、解析xml

String xml =
'''<person>
<name id="2">Hensen</name><age>23</age>
<name id="3">Jack</name><age>20</age>
</person>'''

def xmlSlurper = new XmlSlurper()
def person = xmlSlurper.parseText(xml)

//获取值
println person.name[0].text()
//获取属性
println person.name[0].@id
//遍历获取
person.each { p ->
    println p.name.text()
}

2、遍历xml

  • depthFirst():表示深度遍历所有节点,可以用符号'**'替代这个方法
  • children():表示广度遍历当前节点,可以用符号'*'替代这个方法
//深度遍历
def names = person.depthFirst().findAll{ name ->
    return name.@id == "2" ? true : false
}
println names
//广度遍历
def namess = person.children().findAll { node ->
    return node.@id == "2" ? true : false
}.collect{ node ->
    return node.@id
}
println namess

3、生成xml

在生成xml的过程中,可以使用xmlBuilder.节点(){ 子节点() }的方式生成对应的xml文件

class Computer{
    def name = 'Hensen'
    def count = 2
    def languages = [
            new Language(version: '1.8',value: 'Java'),
            new Language(version: '3.0',value: 'Python')
    ]
}

class Language{
    def version
    def value
}

def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)

def computer = new Computer()
xmlBuilder.computer(name: computer.name, count: computer.count){
    //遍历所有子节点
    computer.languages.each{ lang ->
        language(version: lang.version, lang.value)
    }
}

println sw

输出结果

<computer name='Hensen' count='2'>
  <language version='1.8'>Java</language>
  <language version='3.0'>Python</language>
</computer>

文件操作

1、读取文件

//读取文件的所有行
def file = new File("../Groovy.iml")
file.eachLine { line ->
    println line
}

//读取文件的所有行
def text = file.getText()
println text

//读取文件的前100个字节
def reader = file.withReader { reader ->
    char [] buffer = new char[100]
    reader.read(buffer)
    return buffer
}
println reader

2、拷贝文件

def copy(String srcPath,String destPath){
    try {
        def destFile = new File(destPath)
        if(!destFile.exists()){
            destFile.createNewFile()
        }
        new File(srcPath).withReader { reader ->
            def lines = reader.readLines()
            destFile.withWriter { writer ->
                lines.each { line ->
                    writer.append(line + '\r\n')
                }
            }
        }
        return true
    }catch (Exception e){
        e.printStackTrace()
    }
    return false
}

3、对象读写

def saveObject(Object obj,String path){
    try {
        def destFile = new File(path)
        if(!destFile.exists()){
            destFile.createNewFile()
        }
        destFile.withObjectOutputStream { out ->
            out.writeObject(obj)
        }
        return true
    }catch (Exception e){
        e.printStackTrace()
    }
    return false
}

def readObject(String path){
    try {
        def destFile = new File(path)
        if(destFile ==null || !destFile.exists())return null
        destFile.withObjectInputStream { input ->
            def obj = input.readObject()
            return obj
        }
    }catch (Exception e){
        e.printStackTrace()
    }
    return null
}

猜你喜欢

转载自blog.csdn.net/qq_30379689/article/details/81200026