美文网首页
Gradle 系列之一: Groovy 语法基础

Gradle 系列之一: Groovy 语法基础

作者: yanftch | 来源:发表于2019-12-26 17:30 被阅读0次

    [TOC]

    Groovy是一门jvm语言,特定领域的语言.

    打开Android Studio,随便新建一个Android项目.点击顶部Tools->Groovy Console即可,这时AS会出来一个窗口,专门拿来运行那种临时的Groovy代码的.因为是在本地执行,所以执行速度会非常快.写好代码后点击窗口左上角的三角按钮即可运行代码.

    基础

    变量

    包含基本类型和对象类型;同时变量又包含强类型(类似 java 中的固定类型)和弱类型(类似 JS 中的弱类型)

    强类型定义: 类似 java 中的定义边变量方式
    弱引用定义: 用 def 关键字 定义一个变量

    基本类型和引用类型

    基本数据类型,同 java 中,包含 boolean,int,double,float,byte,char.
    对象类型比如 Double,String等,完全跟 java 互通!
    用法跟 java 用法一致,无需多讲...

    // 基本数据类型
    int a = 1  //定义 int 型数据
    String s1 = "a" // 定义 String 类型数据-通过双引号
    String s2 = 'a' // 定义 String 类型数据-通过单引号
    boolean b1 = false // 定义布尔类型数据
    double d = 1 // 定义 double 类型数据
    double d2 = 3.0
    float f = 2
    def b = 2  // 弱引用类型
    def s = "a" // 弱引用类型,通过赋值表明类型
    

    字符串

    在 Groovy 中字符串分为 java.lang.String 和 groovy.lang.String 两大类. 第一个就是我们常用的 java 中的 String 类,用法并无任何差异; 第二个是 Groovy 中的

    String

    同 java 中的 String 类,一毛一样...

    GString

    有三种常见的定义方法:
    单引号定义

    def gString = 'a'
    

    但是通过打印gString.class发现得到的是java.lang.String,所以结论是通过单引号来定义得到的其实是 java 中的 String 对象

    三个单引号定义

    def gString2 = """ab"""
    

    同上,得到的也是 java 中的 String
    其实跟用单引号定义么啥大的区别,无非就是保持了格式.比如字符串里边包含单引号的话,不需要转义处理了.

    双引号定义

    def gString3 = "abc"
    println(gString3.class) // class java.lang.String
    

    用双引号发现,也是 java 中的 String...

    def hello = "hello ${gString}"
    println(hello)
    println(hello.class) // class org.codehaus.groovy.runtime.GStringImpl
    

    通过${}拼接之后,生成的就是 GString 了...

    新增操作符

    具体可查看 API,下边列几个常用的...
    1.String[int index]
    在 java 中可以直接使用 String.charAt(index)获取 index 位置的字符,在 Groovy 中获取字符串的某个位置的字符可以直接 String[index],其实等同于 java 中的 charAt(), []中的参数可以是某一个具体的 index,也可以是区间,比如[0..2]就表示获取字符串中的前 3 个字符.具体看如下代码

    def str = "abcdefg"
    println(str.charAt(2)) // c
    println(str[2]) // c
    println(str[0..2]) // abc
    

    2. -
    做减法.直接看示例

    def strLong = "hello-world"
    def strShort = "hello-"
    println("${strLong - strShort}") // 输出:world
    

    3.倒序

    println("${strLong.reverse()}") // 输出:dlrow-olleh
    

    4.首字母大写

    println("${strLong.capitalize()}") // 输出:Hello-world
    

    5.是否是数字

    println("a".isNumber()) // false
    println("1".isNumber()) // true
    

    数组/集合

    在 Groovy 里边数组和集合是一回事,都统称为集合吧..
    在 Groovy 中集合可以存放不同类型的数据,而且比 java 中的更加强大,

    // 定义一个数组
    def arr = []
    def arrMut = [1, "a", false, 4] // 存放不同类型数据
    
    // 往数组中添加数据
    arr[0] = "a"
    arr[1] = "b"
    
    println(arr) //[a,b]
    // 根据索引值获取对应的值
    println(arr[1]) // b
    

    数组的遍历,可以采用两种方式: for 循环遍历;each()方法遍历

    // 遍历数组
    // 1.for 循环遍历
    for (index in 0..arr.size() - 1) {
        println("arr 中的元素:${arr[index]}")
    }
    // 2.each{} 遍历
    arr.each {
        println("arr 中的数据:${it}")
    }
    

    map

    作为键值对的 map 结构,定义起来其实跟数组定义差不多..直接看代码即可

    def map1 = ["key1": "value1", "key2": "value2"]
    

    map 中提供了 each 方法方便于遍历

    // 遍历 map
    map.each { k, v ->
        println("map: key = $k  value = $v")
    }
    

    IO

    API

    // IO 操作
    def file = new File("../file.txt")
    file.eachLine {line, lineNo->
        println "lineNo=$lineNo     $line"
    }
    

    方法

    Groovy 中的方法,定义跟java 中没啥区别,但是它有自己的一些特性.

    括号可以省略

    正常方法的写法如下:

    // 定义方法
    def method1(param1, param2) {
        println("param1 = $param1, param2 = $param2")
    }
    // 调用方法
    method1(1, 2) // 输出:param1 = 1, param2 = 2
    

    在 Groovy 中可以直接这么调用

    method1 5, 6 // 输出: param1 = 5, param2 = 6
    

    可见可以直接省略掉括号直接进行方法的调用.

    return 可以省略

    如果省略掉 return 语句,那么 Groovy 中会默认将最后一行当做 return 语句的返回值
    下边两个方法的作用一样

    def returnMethod(int param) {
        return 100 * param
    }
    def returnMethod(int param) {
        100 * param
    }
    

    类-JavaBean

    在 java 中定义 Bean,我们需要提供 set/get 方法,但是在 Groovy 中,完全没必要,直接使用就行,有点类似于 kotlin 中的 data class 似的.

    User user = new User()
    println("user.name = ${user.name}")
    user.name = "xiaoming"
    println("user.name = ${user.name}")
    // 输出:user.name = null
    //      user.name = xiaoming
    class User {
        private String name
    }
    

    逻辑控制

    顺序逻辑

    条件逻辑

    switch/case & if/else

    Groovy中的switch/case和Java还是有点不同的.Java中的switch只支持固定的几种类型,但是Groovy中的switch是支持任意类型的,所以说基本上switch是可以代替if/else了.

    def x = 100
    def result
    switch (x) {
        case 1:
            result = "result = 1"
            break
        case 100:
            result = "result = 100"
            break
        case "hello":
            result = "result = hello"
            break
        case BigDecimal:
            result = "result = big decimal"
            break
        default:
            result = "default"
    }
    println(result) // result = 100
    

    循环逻辑

    Groovy 中的循环逻辑,包含对范围的 for 循环;

    对范围的 for 循环
    def sum = 0
    for (i in 0..10) {
        sum += i
    }
    println("sum = $sum") // sum == 55
    
    对 List 循环
    def list1 = [1, 2, 3, 4, 5, 6]
    for (i in list1) {
        println(i)
    }
    
    对 map 循环

    比 java 中遍历 map 方便多多多了...

    def map1 = ["key1": "value1", "key2": "value2"]
    for (i in map1) {
        println("遍历 map: key = ${i.key}  value = ${i.value}")
    }
    

    闭包

    闭包就是一段代码块.
    有点类似 kotlin 中高阶函数
    可以将闭包当做参数传入方法中去,也可以赋值给变量,然后通过call方法调用闭包,kotlin 中是使用的invoke方法调用

    如下定义一个最简单的闭包:

    def b1 = {
        println "Hello Closure"
    } // 定义一个闭包 b1
    
    b1.call() // 输出:Hello Closure
    

    定义有参数的闭包:

    // 有参数的闭包
    def b2 = { key, value ->
        println "key = $key, value = $value"
    }
    
    b2.call("id", 123) // 输出:key = id, value = 123
    

    有返回参数的闭包:

    // 有参数&返回值的闭包
    def b2 = { key, value ->
        println "key = $key, value = $value"
        return "$key-$value"
    }
    
    def r = b2.call("id", 123) // 输出:key = id, value = 123
    println(r) // 输出:id-123
    

    闭包的 this,owner,delegate

    闭包关键变量(this、owner、delegate)

    def b3 = {
        println "this:$this"
        println "owner:$owner"
        println "delegate:$delegate"
    }
    b3.call()
    // 打印结果:
    //this:ideaGroovyConsole@1b919693
    //owner:ideaGroovyConsole@1b919693
    //delegate:ideaGroovyConsole@1b919693
    

    通过 LOG 可以看到,this,owner,delegate 返回的日志都是一致的.有猫腻...

    • this: 这个关键字同 java 中的 this,表示当前类的方法或者变量,在 Groovy 中表示的是闭包定义处的类
    • owner: 表示的是闭包定以处的类或者对象
    • delegate:表示任意对象,默认与 owner 一致

    进阶

    数据结构-列表

    列表的定义

    在Java中我们定义一个列表一般是这样定义的List list = new ArrayList() 或者 new LinkedList()等等.
    在我们Groovy中定义一个列表只需要让它等于[]即可,也就是def list = [],我们想要往里面添加元素直接往方括号里面加,用逗号隔开就行,比如def list = [1, 2, 3],这里呢会有同学有疑问,这个明明就是Java中的数组嘛,为什么到这里就变成List了呢?这个List是ArrayList还是LinkedList呢?别着急,我们打印下它的类型

    def list = [1, 2, 3]
    println list.class // 输出:class java.util.ArrayList
    

    通过输出可以看到,此种定义方式的格式默认是 ArrayList 的,那么我们该怎么定义一个数组呢?很简单,可以直接使用as 进行强转,或者使用强类型定义

    // 定义数组的两种方式:
    // 第一种:使用[as]关键字,将 List 强转成数组
    def arr1 = [1, 2, 3] as int[]
    // 第二种:使用强类型直接定义
    int[] arr2 = [1, 2, 3]
    
    println arr1.class // 输出:class [I
    println arr2.class // 输出:class [I
    

    同理,我要想实例化一个 LikedList,那么也可以参考数组的定义方式来实现,采用两种方式来定义:

    // 定义一个 LinkedList
    def linkedList1 = [1, 2, 3] as LinkedList
    LinkedList linkedList2 = [1, 2, 3]
    println linkedList1.class // 输出:class java.util.LinkedList
    println linkedList2.class // 输出:class java.util.LinkedList
    

    列表的常见操作

    主要针对增加,删除,查找,排序

    增加

    1.add()
    增加的方法也是add(),跟java 中一样,有两种添加方式:一种是在最后插入元素;另一种是在指定位置插入指定元素

    // 增加
    def addList = [1, 2, 3]
    addList.add(4) //在最后添加一个元素
    addList.add(0, 0) // 在指定位置添加元素
    println addList // [0, 1, 2, 3, 4]
    

    2.leftShift() 或者 <<
    使用leftShift或者<<方法,表示在集合的最后添加一个元素,leftshift()的重载运算符是<<

    // 增加-leftShift
    addList.leftShift(5)
    addList << 6
    println addList // [0, 1, 2, 3, 4, 5, 6]
    

    3.直接使用 +
    还可以直接使用+号进行拼接

    // 增加-直接使用加号
    addList = addList + 7
    println addList // [0, 1, 2, 3, 4, 5, 6, 7]
    
    删除

    1.remove()
    类似 java,直接使用remove(Object o)或者remove(int index) 进行删除,其他的还有removeAll(),removeElement()类似,可自查

    def deleteList = ["A", "B", "C"]
    // 删除-使用 remove
    deleteList.remove("C") // 输出:[A, B]
    deleteList.remove(0) // 输出:[B]
    deleteList.removeAt(0) // 内部实际调用了上边的 remove(index)方法
    

    2.使用减号处理

    // 删除-使用减号
    deleteList = deleteList - "C"
    
    查找

    1.get(index)/List[index]
    等同于 java 中的 get(index)方法或者 kotlin 中的[index]

    // 查找-get()方法
    def searchList = [1, 2, 3, 4, 5]
    println "第二个元素是:${searchList.get(2 - 1)}" // 第二个元素是:2
    println "第三个元素是:${searchList[3 - 1]}" // 第二个元素是:3
    

    2.find(Closure closure)
    返回符合闭包内条件的第一个元素

    //查找-find 返回第一个符合条件的元素
    def findResult = searchList.find { it ->
        (it % 3) == 0
    }
    println "findResult = $findResult" // findResult = 3
    

    3.findAll(Closure closure)
    返回所有符合条件的元素

    //查找-返回所有符合条件的元素
    println searchList.findAll { it ->
        (it % 2) == 0
    } // [2, 4]
    

    4.any(Closure closure)
    any()只要集合中有一个符合条件的,就返回 true

    //查找-any: 只要有符合条件的就返回
    println searchList.any { it ->
        (it % 3) == 0
    } // true
    

    5.every(Closure closure)
    every() 只有当所有的元素都符合条件时,才返回 true

    //查找-every:所有元素都符合条件才返回 TRUE
    println searchList.every { it ->
        (it % 2) == 0
    } // false
    

    6.min()/max()
    minx()/max()分别返回最小的元素和最大的元素

    //查找-返回最小/大值
    println searchList.min() // 1
    println searchList.max() // 5
    

    7.count()
    返回符合条件的元素的个数

    // 查找-count:返回符合条件的元素的个数
    def count = searchList.count { it ->
        (it % 2) == 0
    }
    println "对 2 取余为 0 的个数为:$count" // 2个
    

    数据结构-映射

    映射的定义

    其实就是 java 中的 Map 操作.
    在 java 中我们这么定义 Map:Map map = new HashMap(), 在 Groovy 中的定义方式跟集合差不多,集合中是单元素的,映射是键值对形式的,也就是每个元素都是key:value的形式.

    def defMap = ["name": "Tom", "age": 18, "man": true]
    println defMap // [name:Tom, age:18, man:true]
    

    类似集合,我们打印一下这个 Map 是哪种类型的?

    println defMap.getClass() // class java.util.LinkedHashMap
    

    所以,如果你想定义别的 Map 类型,可以采用等同于集合的处理方式:第一种通过as关键字进行强转;第二种通过强类型定义来定义

    映射的常见操作

    1.添加元素

    添加元素有put()方法,以及中括号直接操作,点操作;添加多个用putAll()
    假如新添加的元素不存在,那么就直接添加;如果已经存在了,那么就会替换对应的 value

    // 添加元素
    defMap.put("height", 100)
    defMap["birthday"] = "2011-11-11"
    defMap.father = "Jack"
    // 此时输出:[name:Tom, age:18, man:true, money:200.56, height:100, birthday:2011-11-11, father:Jack]
    
    2.删除元素

    针对删除元素,目前常用的就是remove()方法

    // 删除元素
    defMap.remove("birthday")
    
    3.根据key 获取 value

    通过 key 获取 value ,Groovy 有提供get(),getAt()方法,同时也提供了方便的操作符获取,比如直接.或者[]来获取

    def defMap = ["name": "Tom", "age": 18, "man": true, "money": 200.56]
    println "key为 name 的 value 是:${defMap.name}" 
    println "key为 name 的 value 是:${defMap.get("name")}"
    println "key为 name 的 value 是:${defMap["name"]}"
    println "key为 name 的 value 是:${defMap.getAt("name")}"
    //上述 4 种方法的输出都是: key为 name 的 value 是:Tom
    
    4.遍历

    遍历主要用到两个方法:each()eachWithIndex(),第二个方法会附带输出当前索引值.

    // 遍历
    defMap.each {
        println "key=${it.key}, value=${it.value}"
    }
    defMap.eachWithIndex { Map.Entry<String, Serializable> entry, int i ->
        println "i=$i, key=${entry.key}, value=${entry.value}"
    }
    

    输出信息:

    key=name, value=Tom
    key=age, value=18
    key=man, value=true
    key=money, value=200.56
    key=height, value=100
    key=father, value=Jack
    i=0, key=name, value=Tom
    i=1, key=age, value=18
    i=2, key=man, value=true
    i=3, key=money, value=200.56
    i=4, key=height, value=100
    i=5, key=father, value=Jack
    
    5.条件查找

    跟 List 差不多,find(),findAll(),count()

    数据结构-范围

    在 Groovy 中,有个 范围的数据结构,其实也很简单,比如要定义一个 1 到 10 的范围,就直接def a = 1..10就行了, 主要用到了..操作符.
    其实所谓的范围,本质上是一个 List.

    // 定义一个范围
    def rangeInt = 1..10 // class groovy.lang.IntRange
    def rangeString = "A".."D" //class groovy.lang.ObjectRange
    

    常用操作

    1.获取范围中某个值
    // 获取范围中某个值
    println rangeInt.get(1) // 索引值为 1 的数字是 2
    println rangeInt[1]
    
    2.范围中是否包含某个值
    // 范围中是否包含某个值
    println rangeInt.contains(4) // 存在则返回 true
    
    3.获取范围第一个/最后一值

    在范围的类定义中,有两个属性:from,to,对应的就是当前范围的第一个和最后一个值.

    // 获取范围的第一个值
    println rangeInt.from // 1
    // 获取范围最后一个值
    println rangeInt.to // 10
    
    4.遍历
    // 遍历
    rangeInt.each {
        println it
    }
    

    相关文章

      网友评论

          本文标题:Gradle 系列之一: Groovy 语法基础

          本文链接:https://www.haomeiwen.com/subject/uljloctx.html