Groovy基础

引言:

Groovy 是一种基于 Java 平台的动态编程语言(指在运行时进行类型检查的语言。在使用动态语言编写程序时,变量的类型不需要在声明时明确指定,而是在运行时根据赋给变量的值来确定类型。动态语言在代码执行过程中会进行类型检查)。它旨在简化和增强 Java 开发,提供了更简洁的语法、闭包、动态类型等特性。Groovy 可以无缝地与 Java 代码互操作,并且可以直接使用 Java 库。下面我们来学习一下Groovy的基础

注:需要有一定的java基础哦


Groovy开发环境配置

  1. 安装Intellij IEDA开发工具:Download IntelliJ IDEA -- The Leading Java and Kotlin IDE
  2. 下载Groovy SDK开发工具:The Apache Groovy programming language - Download
  3. 将Groovy SDK开发工具下的bin文件配置到环境变量中,eg:D:\apache-groovy-sdk-4.0.24\groovy-4.0.24\bin
  4. 检查是否安装成功:groovy -version

学一门语言,第一步该干什么?

  1. 那就是HelloWorld!了

  2. Groovy中可以直接使用java库,也可以直接写java语法

  3. 例如:

    Groovy 复制代码
    HelloWorld.groovy
    
    class HelloWorld{
        public static void main(String[] args){
            System.out.println("Hello World!");
        }
    }
  4. 在Groovy中可以直接调用方法不用写类、main方法

  5. 最终版本:

    Groovy 复制代码
    System.out.println("Hello World!")
    或
    println("Hello World!")
    或
    println "Hello World!"

变量

  1. java是一种强类型语言,Groovy既是强类型语言,也是弱类型语言

    1. 强类型:在定义变量时,必须声明其类型,并且后续不能更改其类型
    2. 弱类型:在定义变量时,无需声明其类型,会自动推断出其类型,并且可以修改
  2. Groovy中使用def来定义弱类型变量,也可以省略def

    Groovy 复制代码
    在java中:
    int a = 1;
    a = "abc"; //编译错误,类型不匹配
    
    在Groovy中:
    使用java的肯定是不行的
    int a = 1;
    a = "abc";//编译错误,类型不匹配
    
    使用def
    def a = 2
    a = "groovy"
    
    省略def
    a = 2
    a = "groovy"
  3. Groovy中的基本数据类型都是以对象的形式存在的,万物皆对象

  4. 证明:

    Groovy 复制代码
    int x=1
    double y=3.14
    char ch='a'
    boolean flag=true;
    
    println x.class  //class java.lang.Integer
    println y.class  //class java.lang.Double
    println ch.class //class java.lang.Character
    println flag.class //class java.lang.Boolean
    
    
    def x=1
    def y=3.14D
    def ch='a'
    def flag=true
    
    println x.class //class java.lang.Integer
    println y.class //class java.lang.Double
    println ch.class //class java.lang.String
    println flag.class //class java.lang.Boolean
  5. 尽量使用def来定义弱类型变量,因为直接使用x = 1更像赋值操作


字符串

  1. 在 Groovy 中,字符串可以使用单引号、双引号和三引号来表示

  2. 证明:

    Groovy 复制代码
    def s1='groovy'
    def s2="groovy"
    def s3='''groovy'''
    println s1.class  //class java.lang.String
    println s2.class //class java.lang.String
    println s3.class //class java.lang.String
  3. 有什么区别呢?

  4. 单引号:用于定义普通的字符串,不支持插值,即不支持在字符串中嵌入变量或表达式,就相当于java的" "字符串

  5. 双引号:用于定义支持插值的字符串,可以在字符串中嵌入变量或表达式,使用 ${} 语法。

  6. 三引号:用于定义多行字符串,支持插值。它允许字符串跨越多行,且保持格式

    Groovy 复制代码
    def name = 'Groovy'
    def message1 = 'Hello, ${name}!'  // 单引号不支持插值
    println message1  // 输出 Hello, ${name}!
    
    def message2 = "Hello, ${name}!"
    println message2  //输出 Hello, Groovy!
    
    ========================================================
    实现下面这种效果:
    Hello, Groovy!
    Welcome to the world of Groovy.
    
    单引号:
    def nam1 = 'Groovy'
    def name2 = 'Hello,'+nam1+'\nWelcome to the world of Groovy.'
    
    双引号:
    def name = 'Groovy'
    def message = "Hello,${name}\nWelcome to the world of Groovy."
    println message
    
    三引号:输出多行字符串,保持格式
    def name = 'Groovy'
    def message = """
    Hello, ${name}!
    Welcome to the world of Groovy.
    """
    
    输出结果:
    Hello, Groovy!
    Welcome to the world of Groovy.
  7. 从例子中可以看出,三引号很灵活吧,我们需要换行时,不需要使用\n


闭包Closure

  1. 在Groovy中,闭包是一种类似于匿名函数的概念,就是一个使用花括号包围的代码块,它可以被赋值给变量或作为参数传递给其他函数,闭包的类型为Closure

  2. 基本语法:{参数列表 -> 代码块} ,其中如果没有参数时,(参数列表 ->) 可省略

  3. 无参数闭包、带参数闭包:

    Groovy 复制代码
    //无参数的闭包
    def closure1={
        println "hello groovy!"
    }
    //使用
    closure1()
    
    
    //带参数的闭包
    def closure2={String name,int age->
        println "hello ${name}:age ${age}"
    }
    //使用
    closure2("wjb",18)
  4. 如果闭包只有一个参数,可以使用隐式参数 it,而不需要显式声明参数。

    Groovy 复制代码
    def greet = {
        println "Hello, ${it}!"
    }
    
    greet("Groovy")  // 输出 Hello, Groovy!
  5. 闭包的返回值:

    Groovy 复制代码
    def closure={
        println "hello ${it}"
        return "123" //可以省略return
    }
    def result=closure("groovy")
    println "result="+result
  6. 闭包的类型是Closure,Closure实现了Runnable、Callable接口,Closure实现了call方法和run方法

    Groovy 复制代码
    public abstract class Closure<V> extends GroovyObjectSupport implements Cloneable, Runnable, GroovyCallable<V>, Serializable {}
  7. 我们可以使用call、run方法来调用我们的闭包

    Groovy 复制代码
    def closure1={
        println "hello groovy!"
    }
    closure1.run()  //hello groovy!
    closure1.call() //hello groovy!
  8. 为什么呢?

  9. 我们先来看看run方法内部干了什么:

  10. 可以看到run方法调用了call方法

  11. 所以我们来看看call方法干了什么

  12. 可以看到call方法调用了传递任意数量的参数的call方法,最后找到当前的方法doCall,并调用

  13. 难道是Closure的docall方法?不对,因为Closure内部的docall方法最终还是调用了传递任意数量的参数的call方法,那是不是我们定义的闭包中有docall方法呢?我们来看看class文件(Groovy也是在JVM上运行的,也就是说,Groovy代码会编译成字节码,然后在JVM上执行)

  14. 可以看到,我们写了一小段代码,但是class文件有很多内容,这都是Groovy编译器帮我完成的,编译器会自动帮你创建一个和文件名同名的类,把你的代码放入run方法,并在main方法中调用run

  15. 从class文件中可以看到_run_closure1继承了Closure类,所以call方法中,会调用到_run_closure1的docall方法

  16. 闭包可以作为方法的参数传递

  17. 大家可以想一下下面这段代码,是java语法还是Groovy语法呢?

    Groovy 复制代码
    int x=fab(5)
    int fab(int number){
        int result=1;
        1.upto(number,{num -> result *= num})
        return result
    }
    println x;
  18. 当然是Groovy了,因为方法内有闭包,闭包是Groovy的语法,我们要记住Groovy 可以无缝地与 Java 代码互操作,并且可以直接使用 Java 库,并且可以直接使用java的语法

  19. 这个代码中我们调用了int的api upto(用来迭代从当前数字到目标数字,类似于 Java 中的 for 循环,但更加简洁和直观。)

  20. upto方法的参数需要传递一个Closure

  21. 也可以先定义closure再传入,但是不能在fab方法外部定义,必须定义在fab方法作用域之内

    Groovy 复制代码
    int fab(int number) {
        int result = 1
        def closure = { num -> result *= num } 
        1.upto(number, closure)
        return result
    }
  22. 当方法的最后一个参数是Closure时,可以将闭包放在方法调用的括号之外

    Groovy 复制代码
    int fab(int number) {
        int result = 1
        1.upto(number){ num -> result *= num }
        return result
    }
  23. 闭包中有三个关键变量:this、owner、delegate,这些变量在闭包中用来引用不同的上下文对象

  24. 从源码中可以看出owner、delegate是Closure类的两个成员变量,并且是在构造方法中进行赋值的

  25. this 变量指向定义闭包的类(即包含闭包的类)。

    1. 代码:

      Groovy 复制代码
      class A{
          class B{
              void run(){
                  def closure = {
                      println "run:"+this //run:org.example.study_1.closure.A$B@3b74ac8
                  }
                  closure()
              }
          }
      
          void print(){
              new B().run()
              def closure = {
                  println "print:"+this //print:org.example.study_1.closure.A@7d286fb6
              }
              closure()
          }
      }
      
      new A().print()
    2. 代码解释:run方法的closure闭包是定义在B类中的,所以this指向的是B的实例;print方法的closure闭包是定义在A类中的,所以this指向的是A的实例

    3. 证明:看看对应的class文件

      1. 我们先看看A类的print方法,可以看到我们定义一个闭包,groovy编译器会为我们创建一个Closure对象,那在java中Object closure = new _print_closure1(this, this);的this是指什么?是不是指向当前这个对象--》A的实例,所以print方法的closure闭包的this指向的是A的实例,那么owner、delegate的值是不是和this相同,是相同的,大家可以测试一下

      2. 我们再来看看B类的run方法,原理是不是和上面的一样?对的

    4. 总结:this指向的是闭包外第一个类的实例

  26. owner 变量指向定义闭包的对象,可能是类或闭包。

    1. 代码:

      Groovy 复制代码
      class Example {
          void run() {
              def nestedClosure = {
                  def innerClosure = {
                      println "innerClosure owner: " + owner  //org.example.study_1.closure.Example$_run_closure1@6aa61224
                  }
                  innerClosure()
                  println "nestedClosure owner: " + owner //org.example.study_1.closure.Example@30c8681
              }
              nestedClosure()
          }
      }
      
      new Example().run()  
    2. 代码解释:owner 变量指向定义闭包的对象,先看看innerClosure闭包的owner,innerClosure闭包是定义在nestedClosure闭包内的,那么owner和nestedClosure指向同一个类的实例;那nestedClosure闭包的owner呢?它是定义在Example类内的,所以owner指向的是Example的实例

    3. 证明:看看对应的class文件

      1. 我们先看innerClosure闭包,Groovy编译器帮我们创建了对象,在java中,Object innerClosure = new _closure2(this, this.getThisObject());的this指的是哪个类的实例?是_run_closure1这个类吧;我们再来看看nestedClosure闭包,在java中,Object nestedClosure = new _run_closure1(this, this);的this指的是哪个类的实例?是Example这个类吧。

    4. 总结:如果闭包定义在类中,则owner指向的是类的实例;如果闭包外还是闭包,则owner指向的是外层闭包的实例对象

  27. delegate 变量指向代理(任意)对象,默认情况下与 owner 相同,但可以被显式更改。

    1. 代码1:默认情况下,delegate 和owner相同

      Groovy 复制代码
      class Example {
          void run() {
              def nestedClosure = {
                  def innerClosure = {
                      println "innerClosure owner: " + owner  //org.example.study_1.closure.Example$_run_closure1@6aa61224
                      println "innerClosure delegate: " + delegate  //org.example.study_1.closure.Example$_run_closure1@6aa61224
                  }
                  innerClosure()
                  println "nestedClosure owner: " + owner //org.example.study_1.closure.Example@30c8681
                  println "nestedClosure delegate: " + delegate //org.example.study_1.closure.Example@30c8681
              }
              nestedClosure()
          }
      }
      
      new Example().run()
    2. 代码解释:默认情况下,owner和delegate是相同的

    3. 证明:从构造方法中可以看出,owner直接赋值给了delegate

    4. 代码2:修改delegate

      Groovy 复制代码
      //修改默认的delegate对象
      class Person {
      }
      Person p=new Person();
      def nestClouser = {
          def innerClouser = {
              println "innerClouser:" + this  //org.example.study_1.closure.ClosureTest4@6cb6decd
              println "innerClouser:" + owner //org.example.study_1.closure.ClosureTest4$_run_closure1@40317ba2
              println "innerClouser:" + delegate //org.example.study_1.closure.Person@3c01cfa1
          }
          innerClouser.setDelegate(p) //修改delegate
          innerClouser.call()
      }
      nestClouser.call()
    5. 代码解释:修改delegate的指向为Person

    6. 证明:Closure只提供了setDelegate方法,并没有提供setOwner方法

    7. 总结:在默认情况下delegate是等于owner的,delegate可以被修改

  28. 闭包的委托策略:闭包的委托策略决定了闭包在查找属性和方法时的优先级。Groovy 提供了几种不同的委托策略,可以通过 resolveStrategy 属性来设置

  29. 委托策略,默认策略是Closure.OWNER_FIRST

    1. Closure.OWNER_FIRST,优先级:owner > delegate,闭包首先在其owner上查找属性和方法,如果找不到,则在delegate上查找

    2. Closure.DELEGATE_FIRST,优先级:delegate > owner,闭包首先在其delegate上查找属性和方法,如果找不到,则在owner上查找

    3. Closure.OWNER_ONLY,闭包仅在其owner上查找属性和方法,忽略delegate

    4. Closure.DELEGATE_ONLY,闭包仅在其delegate上查找属性和方法,忽略owner

    5. Closure.TO_SELF,闭包仅在其自身上查找属性和方法,忽略owner和delegate

  30. 代码:

    Groovy 复制代码
    class Student{
        String name
        def pretty={"My name is ${name}"}
        String toString(){
            pretty.call()
        }
    }
    def student=new Student(name: "groovy") //Groovy编译器会帮我们自动添加一个构造方法
    
    class Teacher{
        String name
    }
    def teacher=new Teacher(name:'andy')
    
    println 'pretty: '+student.toString() // My name is groovy
    println 'delegate: '+student.pretty.delegate  //delegate: com.example.Student@<hashcode>
    
    student.pretty.delegate=teacher
    println 'delegate: '+student.pretty.delegate //org.example.study_1.closure.Teacher@563e4951
    //闭包的委托策略
    student.pretty.resolveStrategy=Closure.DELEGATE_FIRST
    
    println 'pretty: '+student.toString() //pretty: My name is andy
  31. 代码解释:我们这里使用的是Closure.DELEGATE_FIRST策略,那么它就会先从delegate中查找属性和方法


Gradle中常用的数据结构

  1. List:

    1. 定义:

      Groovy 复制代码
      //使用ArrayList
      def list=new ArrayList()
      
      //使用Groovy
      def list=[1,2,3,4,5]
      println list.class //class java.util.ArrayList
    2. 常用方法:

      Groovy 复制代码
      //list大小
      println list.size()
      
      ===========添加元素===========
      //使用add方法添加元素
      list.add(6)
      //使用groovy的<<添加元素
      list<<2 
      //也可以使用+添加元素
      def plusList=list+5
      //指定下标,添加元素
      plusList.add(3,9)
      
      ===========删除元素===========
      //删除下标位置的元素
      list.remove(2) 
      //删除指定的元素
      list.removeElement(2)
      //删除符合条件的元素
      list.removeAll{
          return it%2!=0
      }
      //使用-删除元素
      println list-[2,3,4] //将所有数值为2,3,4的全部remove
      
      
      ===========查找元素===========
      //查找满足条件的第一个数据
      int result=findList.find{
          return it%2 == 0
      }
      //查找所有满足条件的数据
      def result2=findList.findAll({
          return it%2 !=0
      })
      //查找是否有满足条件的数据
      def result3=findList.any{
          return it%2 ==0
      }
      //查找是否全部满足条件
      def result4=findList.every{
          return it%2 ==0
      }
      //查找最大值与最小值
      def result5=findList.min{
          return it
      }
      def result6=findList.max{
          return it
      }
      //统计满足条件的元素个数
      int result7=findList.count{
          return it>0
      }
      
      ===========排序元素===========
      //升序
      sortList.sort()
      //降序
      sortList.reverse()
      //根据条件排序
      sortList2.sort{
          it.length()
      }
      
      ===========遍历元素===========
      def list=[1,2,3,4,5]
      //传统的for循环
      //for-in循环
      for (element in list) {
          println element
      }
      //each方法
      list.each { element ->
          println element
      }
      //eachWithIndex方法
      list.eachWithIndex { element, index ->
          println "Index $index, Value $element"
      }
      //iterator方法
      def iterator = list.iterator()
      while (iterator.hasNext()) {
          println "Iterator: ${iterator.next()}"
      }
  2. Map

    1. 定义:

      Groovy 复制代码
      //使用java
      def map = new HashMap<String,Integer>()
      
      //使用Groovy
      //定义一个<Integer,String>
      def map = [1:"one",2:"two"]
      println map.getClass() //class java.util.LinkedHashMap
      //定义一个<String,String>
      def colors=[red:'ff0000',green:'00ff00',blue:'0000ff'] //会将red转换成String
      //可以强转为HashMap
      def colors=[red:'ff0000',green:'00ff00',blue:'0000ff'] as HashMap
    2. 常用方法:

      Groovy 复制代码
      def colors=[red:'ff0000',green:'00ff00',blue:'0000ff']
      
      //使用key获取value 
      println colors['red'] 或 println colors.red
      
      
      ===========添加元素===========
      //使用put方法
      //使用.
      colors.yellow='ffff00'
      //往map中再添加一个map
      colors.map = [key1:1,key2:2]
      
      ===========移除元素===========
      //使用remove方法
      colors.remove(key)
      
      ===========遍历元素===========
      //使用each
      teachers.each { key, value ->
          println "key=${key}---value=${value}"
      }
      //带索引
      teachers.eachWithIndex{ def key,def value,int index->
          println "index=${index}---key=${key}---value=${value}"
      }
      
      
      ===========查找元素===========
      //查询符合条件的元素
      def entry=teachers.find{def teacher ->
          return teacher.value.name=='groovy'
      }
      //查询符合条件的所有元素
      def entry=teachers.findAll{def teacher ->
          return teacher.value.name=='groovy'
      }
      //查找符合条件的元素个数
      def count=teachers.count{def teacher ->
          return teacher.value.name=='groovy'
      }
      
      ===========排序元素===========
      //注意:map会返回一个新的map   list是在原来的list中进行排序
      def sort=teachers.sort{def t1,def t2 ->
          return t1.key > t2.key ? 1 : -1
      }
  3. Range

    1. 在 Groovy 中,Range 是一个非常实用和灵活的特性,可以用来表示一系列连续的值。这些值可以是数字、字符等。

    2. 定义:

      Groovy 复制代码
      //数字范围
      def numberRange = 1..5
      
      //字符范围
      def charRange = 'a'..'e'
    3. 常用方法:

      Groovy 复制代码
      def range=1..10
      //获取指定下标的元素
      println range[0]
      //是否包含某元素
      println range.contains(8)
      //使用in
      println 3 in range
      //起点
      println range.from 
      //终点
      println range.to   
      
      ===========遍历元素===========
      //使用each
      range.each {
          println it
      }
      使用for-in
      for(i in range){
          println i
      }
      
      ===========switch-case===========
      def getGrade(Number score){
          def result
          switch(score){
              case 0..<60:
                  result='不及格'
                  break;
              case 60..100:
                  result='及格'
                  break;
              default:
                  result='输入异常'
          }
          return result
      }
      println getGrade(50)
      println getGrade(80)
      println getGrade(120)

面向对象语法

  1. 在Groovy中,所有的类都实现了GroovyObject接口

  2. 在Groovy中,所有类型默认都是public

  3. 在Groovy中,万物皆对象

    Groovy 复制代码
    int x=1
    double y=3.14
    char ch='a'
    boolean flag=true;
    
    println x.class  //class java.lang.Integer
    println y.class  //class java.lang.Double
    println ch.class //class java.lang.Character
    println flag.class //class java.lang.Boolean
  4. Groovy会自动为属性提供set/get方法,并且会将属性私有化:

    Groovy 复制代码
    class Person{
        String name
        Integer age
    }
    
    
    //使用
    def person = new Person()
    person.setName('Alice')
    person.setAge(18)
    println 'name:'+ person.getName() //name:Alice
    println 'age:' + person.getAge() //age:18
    1. 证明:
  5. Groovy中特有的trait关键字,类似于接口

    1. 为什么类似于接口?

      1. 看看它的class文件就知道了
      2. 可以看到DefaultAction1最后被编译成了interface
    2. trait可以包含方法(抽象方法、具体方法、私有方法)、属性

      Groovy 复制代码
      trait DefaultAction {
          def actionName = 'trait'
          int step= 10
          abstract void eat()
      
          //void eat()  //不允许,接口中才可以 
      
          void play(){
              println 'I can play!'
          }
      
          private void test(){
              println 'test()'
          }
      }
    3. trait中的方法冲突:如果一个类实现了多个trait,并且这些trait中有同名方法,Groovy会要求类明确指定使用哪个trait的方法,或者覆盖该方法。

      Groovy 复制代码
      trait A {
          void greet() { println "Hello from A" }
      }
      
      trait B {
          void greet() { println "Hello from B" }
      }
      
      class C implements A, B {
          void greet() {
              A.super.greet()  // 明确调用A trait中的greet方法
          }
      }
      
      def c = new C()
      c.greet()  // 输出: Hello from A
    4. trait中可以有静态方法,接口没有

      Groovy 复制代码
      trait Logger {
          static void log(String message) {
              println "[LOG] $message"
          }
      }
      class LoggerTest implements Logger{
      }
      
      LoggerTest.log("wq")
      
      //Logger.log("wq") //这种是不允许的
    5. trait有构造方法和静态代码块,接口并没有

      Groovy 复制代码
      trait Initializable {
          { println "Initializing trait" }
          static {
              println 'static'
          }
      }
      
      class MyClass implements Initializable {
          MyClass() {
              println "Initializing class"
          }
      }
      
      def obj = new MyClass()
      //输出:
      static
      Initializing trait
      Initializing class
    6. trait还有一些注解,例如:@SelfType----注解用于限制trait只能被特定类型的类实现、@Delegate----注解可以将trait中的方法委托给另一个对象等等,这里就不一一介绍了

    7. 总结:trait类似于接口,功能比接口多

JSON解析

  1. 使用Gson:com.google.code.gson:gson:2.8.9

    Groovy 复制代码
    Gson gson = new Gson();
    Person p1 = new Person(name:"jack",age:18)
    String json = gson.toJson(p1)
    println "json:$json"
    Person p2 = gson.fromJson(json, Person.class); 
    String jsonOutput = gson.toJson(p2); 
    println "jsonOutput:$jsonOutput" //{"name":"jack","age":18}
  2. 使用Groovy自带的json工具:JsonOutput

    Groovy 复制代码
    //对象转成json字符串
    def list=[new Person(name:'jack',age:18),
                new Person(name:'Alice',age:18)]
    println JsonOutput.toJson(list) //[{"name":"jack","age":18},{"name":"Alice","age":18}]
    //格式化
    def json=JsonOutput.toJson(list)
    println JsonOutput.prettyPrint(json)
    
    //json字符串转成对象
    def jsonSluper=new JsonSlurper()
    def object=jsonSluper.parse("[{\"age\":18,\"name\":\"jack\"},{\"age\":18,\"name\":\"Alice\"}]".getBytes())
    println object
    
    def object2=jsonSluper.parse("[{\"abc\":\"jack\"}]".getBytes())
    println object2.abc
    
    
    
    def jsonSlurper = new JsonSlurper()
    def jsonString = '[{"name":"jack","age":18},{"name":"Alice","age":18}]'
    def jsonObject = jsonSlurper.parseText(jsonString)
    
    // 手动转换为 Person 对象
    def personList = jsonObject.collect { map ->
        new Person(name: map.name, age: map.age)
    }
    
    println personList // 输出 [Person(name: jack, age: 18), Person(name: Alice, age: 18)]

XML解析

  1. 使用Groovy自带的XmlSlurper解析xml:

    Groovy 复制代码
    final String xml='''
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.jvm_demo_20200601">
        <test>12345</test>
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".MainActivity2">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    '''
    
    //解析XML数据
    def xmlSluper=new XmlSlurper()
    def result=xmlSluper.parseText(xml)
    println result.@package //com.example.jvm_demo_20200601
    println result.test.text() //12345
    //读取有域名空间的节点
    result.declareNamespace('android':'http://schemas.android.com/apk/res/android')
    println result.application.@'android:allowBackup'  //true
    println result.application.activity[0].@'android:name'  //.MainActivity
    println result.application.activity[1].@'android:name'  //.MainActivity2
    
    //遍历XML节点
    result.application.activity.each{activity ->
        println activity.@'android:name'
    }
  2. 使用Groovy自带的MarkupBuilder生成xml格式数据

    Groovy 复制代码
    /**
     * 生成XML格式数据
     * <html>
     *     <title id='123',name='android'>xml生成
     *          <person></person>
     *     </title>
     *     <body name='java'>
     *         <activity id='001' class='MainActivity'>abc</activity>
     *         <activity id='002' class='SecActivity'>abc</activity>
     *     </body>
     * </html>
     */
    def sw=new StringWriter()
    def xmlBuilder=new MarkupBuilder(sw)
    xmlBuilder.html(){
        title(id:'123',name:'android','xml生成'){
            person()
        }
        body(name:'java'){
            activity(id:'001',class:'MainActivity','abc')
            activity(id:'002',class:'SecActivity','abc')
        }
    }
    println sw

文件操作

Groovy 复制代码
def file=new File("D:\\JAVA\\Study_Groovy\\test.txt")
//遍历文件
file.eachLine { line ->
    println line
}

//返回所有文本
def text=file.getText()
println text

//以List<Stirng>返回文件的每一行
def text=file.readLines()
println text.toListString()

//以java中的流的方式读取文件内容
def reader=file.withReader{reader ->
    char[] buffer=new char[100]
    reader.read(buffer)
    return buffer
}
println reader
//写入数据
file.withWriter { writer ->
    writer.write("abc")
}
相关推荐
天才奇男子1 小时前
数据库约束(2)
android·数据库·mysql·adb
剑客狼心6 小时前
Android Studio:相对布局 RelativeLayout
android·android studio·relativelayout
安小牛6 小时前
Android Studio 下载Gradle失败解决方法
android·ide·android studio
dilvx6 小时前
回退 android studio emulator 的版本
android·ide·android studio
清和已久6 小时前
简述mysql 主从复制原理及其工作过程,配置一主两从并验证。
android·mysql·adb
dilvx7 小时前
android 动态库加载机制
android
立志成为小胖纸的男人8 小时前
Android内存性能优化量化指标
android·性能优化
*老工具人了*11 小时前
mysql 5.7安装
android·mysql·adb
qq_3988989312 小时前
解决虚幻Unreal Engine手动配置安卓打包环境后无法识别SDK问题
android·游戏引擎·虚幻
剑客狼心13 小时前
Android studio:顶部导航栏Toolbar
android·ide·android studio