Groovy basic learning

table of Contents

1.1.1 Introduction

1.1.2 Basic syntax

1.2.1 Keyword explanation

1.2.2 Basic

 1.2.2_a Range operator

1.2.2_b Assignment operator

1.2.2_c loop (for-in statement)

 1.2.2_d can directly declare key-value pairs

1.2.2_e method (default parameters)

1.2.2 Use of_f Object

 1.2.2 Use of_g get/set

1.2.2_h Branch printing shortcut

1.2.2_i The use of ternary operator

1.2.2_j collection

1.1.3 Language Features

 1.1.3_a Return can be omitted, the default is public

1.1.3_b Constructor

1.1.3_c can ignore parentheses

1.1.3_d get/set 

1.1.3_e Before language execution 

1.1.3_f equals and == and is()

1.1.3_g Undeclared variables still cannot be ++

1.1.3_h Use of <<

 1.1.3_i safe value

1.1.3_j try/catch

 

2.1.1 File handling

2.1.2 Database processing

2.1.3 XML/JSON/Excel processing

 

 


1.1.1 Introduction

        I have learned Groovy language quickly in the past few days, and I haven't finished it yet. Make a record first, and then you can look at the previously learned materials.

First of all, you still need to have a foundation of JAVA, otherwise it is not that simple to get started.

I don't know how to write Java comparison code, it's too time-consuming, you probably have a look.

There is no general standard for the knowledge I learned.

The examples cited are also knowledge points that I am not familiar with, or I do not know. Because we are going to change companies next year, this is equivalent to reviewing previous knowledge.

Install the groovy environment on your own Baidu.

1.1.2 Basic syntax

  • Meeting is still the old rule, hello! groovy.
class test {

    static void main(String[] args) {
        println("hello groovy!");
    }
}
  • 1.2.1 Keyword explanation

  def: Equivalent to Object, the name of the definition method used, the name of the definition field, the name of the array, and the definition of Bean can all be declared with def. Need to avoid overlapping definitions with basic types, for example: def String user

  assert: Assert, judge whether the passed parameter is legal, the program will be terminated directly according to the exception, and reduce the use of this keyword, which will cause a lot of performance waste.

  • 1.2.2 Basic

  •  1.2.2_a Range operator

    // 范围
    def range = 5..10;
    println(range);
    println(range.get(3));

    // 结果
    5..10
    8
  • 1.2.2_b Assignment operator

 // 除余
 int a = 5;
 int b = 2;
 def x = a %= b;
 println(x);
 if ((a %= b) == 1) {
     println(true);
 } else {
     println(false);
 }

//结果
1
true
  • 1.2.2_c loop (for-in statement)

  // for-in语句 
  def range = 5..10;

  for (int r in range) {
      print(r + ",");
  }
   // 结果
   5,6,7,8,9,10,
--------分割线-------------   

  int[] arr = [0, 1, 2, 3, 4];
  for (int i in arr) {
       println(i);
  }
  // 结果
  0
  1
  2
  3
  4
  •  1.2.2_d can directly declare key-value pairs

     def employee = ["key": 1, "name": "Jokn", "Age": 30];
     // 不需要声明属性类型,def可以忽略
     for (emp in employee) {
          println(emp);
     }

    //结果
    key=1
    name=Jokn
    Age=30
  • 1.2.2_e method (default parameters)

   // 可以直接在参数里赋值
    static def someMethod(int a, int c = 1) {
        int d = a + c;
        return d;
    }

    static void main(String[] args){
        // 调用的时候,分两种方式
        int result = someMethod(2);
        println(result);
        // 可以直接传入新参数,进行计算
        int result2 = someMethod(5, 5);
        println(result2);
    }

    // 结果
    3
    10
  • 1.2.2 Use of_f Object

class User implements Serializable {

    private String name;
    private String age;
    private String sex;

    /**
     * 可以忽略get/set
     * @return
     */
    String getName() {
        return this.name;
    }

    void setName(String name) {
        this.name = name;
    }

    /**
     *  构造器,避免使用def
     */
    User() {}

}
  •  1.2.2 Use of_g get/set

  def user = new User();
  // with:可以忽略大量的前缀,例如user.setName()
  user.with {
       name = 'Tom'
       age = 50
       sex = '男'
  }
  // set/get可以直接调用
  user.sex = "女"
  user.name = "something"

  println "name=${user.name} age=${user.age} sex=${user.sex}"


  // 结果
  name=something age=50 sex=女
------------------分割线----------------------------

  // 第二种直接声明,构造器都不需要
  def user2 = new User(name: "huanfeng", age: 22, sex: "男")
  // 输出的时候,需要双引号,否则会直接报错
  println "${user2.name} ${user2.age} ${user2.sex}"

  // 结果
  huanfeng 22 男
  • 1.2.2_h Branch printing shortcut

  // 可以忽略括号,但是有的方法需要
  // “\”这个符号并没有换行,只有相当于tab键的空格
  // 自动换行,使用三个多个双引号或单引号
  println("1111111111111111111111111111111111111 1\
        2 \
        3")
   // 结果
1111111111111111111111111111111111111 1        2         3

  // 三个双引号框起后,里面的空格也会直接输出,并不会换行处理
  println("""111111111111111111
222222222222222222
333333333333333333""")

  // 结果
111111111111111111
222222222222222222
333333333333333333
  • 1.2.2_i The use of ternary operator

    /**
     * 三元运算的简写只能用来判断非空
     * @param name
     * @return
     */
    static def check(String name) {
        assert name
        def result = name ?: "Unknown"
        // 可以省略return
        result
    }

    /**
     * 三元运算还是需要按照以前Java的格式
     * @param str
     * @return
     */
    static def checkNum(String str) {
        def reulst = str.length() > 3 ? str : "xiaoyu"
        reulst
    }
  • 1.2.2_j collection

 

1.1.3 Language Features

  •  1.1.3_a Return can be omitted, the default is public

    def check() {
        def result = "Unknown"
        // 可以省略return,分号也可以忽略
        result
    }
  • 1.1.3_b Constructor

class{
    // 空构造器,尽可能避免使用def
    MyClass(){
    
    }
}
  • 1.1.3_c can ignore parentheses

class{
    static void main(String[] args){
        // 结果都是相同的 Hello World!
        println("Hello World!")
        println "Hello World!"
    }

    // 方法体的命名不可以忽略
    def test(){
    }

}
  • 1.1.3_d get/set 

class User{

    def name;
    int age;
    String sex;
    blooean flg;
    dobule num
    List<String> list

    // 可以忽略Java的get/set方法声明
    
    String toString() {
        "${name},${age},${sex},${flg},${num}"
    }

}
  • 1.1.3_e Before language execution 

class{
    // 执行错误,执行前编译器不会检查闭包内的代码
    test(){
        head{}
        body{}
    }
    // 异常 Error:(32, 5) Groovyc: unexpected token: test
    
    // 正确写法(执行时每行去检查,编译无错后运行代码)
    test(){
        head(){}
        body(){}
    }
}
  • 1.1.3_f equals and == and is()

class{
    // 排除掉了空指针异常(NullPointerException)
    def num1
    def num2
    // == 等价于java的equals方法
    if (num1 == (num2 = 2)) {
         println "相等"
    } else {
         println "不相等"
    }
    if (num1.equals(num2)) {
         println "相等"
    } else {
         println "不相等 ${num2}"
    }
    // is()等价于java的==方法
    if (num1.is(num2++)) {
        println "相等"
    } else {
        println "不相等 ${num2}"
    }

    // 结果
    不相等
    不相等 2
    不相等 3

}
  • 1.1.3_g Undeclared variables still cannot be ++

class{
    
    static void main(String[] args) {
         def i
        println i++
        // Exception in thread "main" java.lang.NullPointerException: Cannot invoke method next() on null object
    }
    
}
  • 1.1.3_h Use of <<

class{
    
    static void main(String[] args){
        def list =[1,2,3]
        // 和add方法一样
        list << 0
        println list
        // 结果
        // [1, 2, 3, 0]
--------------分割线------------------------
        // {}里不能使用"," 编译器直接显示报错
        // 这里的语言特性不懂,有问题,语言的bug吗,取不出来值
        def json = {
                    name:"Tom"
                    sex:"猫"
                    }
        // 闭包里可以写进变量,但是不可以拿出来
        json << [age:21]
        println json.toString()
        json.each {
            println it
        }
    }

}
  •  1.1.3_i safe value

class{
    
    static void main(String[] args){

    Person person = new Person()
    // 错误赋值方式(NullPointerException),这里又有一个语言特性的问题,又是一个坑点
    // person.character.lively = "活泼"
    // person.character.lively << "1"
    Character characters = new Character();
    characters.lively = "123"
    println(characters.lively)

    person.with {
        person.character =
                characters
    }
    // 学到这里,我已经开始吐槽了,说好的
    if (person != null) {
        if (person.character != null) {
            println "结果:" + person.getCharacter().getLively().toString()
        }
    }
    println person.character?.lively
    }

   static class Person {
        private String name
        private String year
        private Character character

        private Character getCharacter() {
            character
        }

    }

    static class Character {
        private def lively

        private def getLively() {
            lively
        }

        String toString() {
            "${lively}"
        }
    }

}
  • 1.1.3_j try/catch

try {
    // ...
} catch (any) {
    // 异常处理
}

// 和下面一样
try {
    // ...
} catch (Exception e) {
    // 异常处理
}
  • 1.1.3_h Optional parameters

class Example {
    static void main(String[] args) {
        test2(1, 3)
        // 可选参数可以不用传值
        test3(1)
        test3(2, "12", "213")
        // 结果
        5
        1,[]
        2,[12, 213]

    }

    def static test2(x, num = 10) {
        println(x = 2 + num)
    }

    def static test3(x, String[] src) {
        println("$x,$src")
    }

    def static test4(x, String... arg) {
        println("$x,$arg")
    }

}
  • 1.1.3_i assignment use

package com.lsl

import org.junit.Test

/**
 * @ClassName StringVoluationTest
 * @Description TODO
 * @Author lisonglin
 * @Date 2020/12/12 14:10
 * @Version 1.0
 */
class StringAssignmentTest {

    def param1, param2, param3

    def caseTest(param1, param2, param3) {
        println("param1:$param1,param2:$param2,param3:$param3")
    }

    @Test
    public void changeOutOrderTest() {
        def StringAssignmentTest stringAssignmentTest = new StringAssignmentTest();
        // 没有任何效果,赋值无视
        stringAssignmentTest.caseTest(param2 = "12", param1 = 2, param3 = 10)
        // 不行,运行报错
        // stringAssignmentTest.caseTest(param2 : "12", param1 : 2, param3 : 10)
        // 赋值方式还是需要在外层申明才有效
        param3 = "12"
        param1 = 10
        param2 = 5
        stringAssignmentTest.caseTest(param1, param1, param2)
    }

    @Test
    public void stringPattern() {
        def paramPattern = /.*foo\.* /
        println(paramPattern)
    }

    @Test
    public void handyAssignmentTest() {
        // 返回一个数组
        def (firstParam, lastParam) = StringAssignmentTest.splitStringMethod("name Tom")
        // 可以直接分割字符串传给两个参数,不需要繁重的赋值过程
        println("$firstParam,$lastParam")
        // 结果 : name,Tom

        // 可以直接替换两个值
        def age = 11, age2 = 12
        (age, age2) = [age2, age]
        println("age:$age,age2:$age2")
        // 结果 : age:12,age2:11

        // 当赋值数组多出数值,会自动忽略掉多余对象值
        def (String strA, String strB) = ["AA", "BB", "CC", "DD"]
        println(strA + "," + strB)
        // 结果:AA,BB

        // 相反需要赋值对象的值少了,还是会报空指针异常
        def (String strC, String strD) = ["CC"]
        // 神奇的是,如果只取出赋值对象有值的话,并没有发生异常
        println(strC)
        // 结果 : CC
        println(strC, strD)
        // 结果 :MissingMethodException
    }

    def static splitStringMethod(param) {
        param.split(" ")
    }

}
  •  

2.1.1 File handling

  • Read file

class test{
    
    static void main(String[] args){
         def file = new File("C:\\Users\\12134\\Desktop\\个人进阶之旅\\Groovy\\user.txt");
         file .eachLine {
                // 声明文件内的文本属性名叫lines,然后用$符号可以使用,输出里面的内容
            lines -> println "$lines"
        }

        // 不能在{}格式里写代码,需要声明变量后,再用来使用
        def lineFiles = file.readLines();
        lineFiles.each {
            println it.toLowerCase()
        }

        // 读取每一行,分割文本,CSV文件分割很好用
        def eachFile = file.splitEachLine(":") {
            println "类型=${it[0]} 内容=${it[1]}"
        }

        // 处理二进制文件,以字节访问文件,和这个方法一样eachLine
        file.eachByte {
            print it;
        }
        
        new File("C:\\Users\\12134\\Desktop\\个人进阶之旅\\Groovy").eachFile {
            // 获取目录下的文件名
            println it.getName()
            // 获取文件里的文本,不能直接读取Excel文件
            // println it.getText('utf-8')
        }

        // 遍历路径下的所有文件,忽略不是文件夹
        def file2 = new File("C:\\Users\\12134\\Desktop\\个人进阶之旅")
        file2.eachDir {
            println(it.getName())
        }

        def dir = new File("C:\\Users\\12134\\Desktop\\个人进阶之旅\\Groovy")
        if (dir.isDirectory()) {
            dir.eachFileMatch(~/.*\.txt/) { File it -> println it.name } //使正则表达式匹配文件名
        }

        // 遍历所路径下的子文件目录
        file2.eachDirRecurse {
            directory -> println directory
        }

        // 递归地将目录大小计算为其所有文件的总大小。
        long fileSize = file2.directorySize();
        println(fileSize)

        /**
         *  FileType有三种类型
         *      FILES:文件,不包括文件夹
         *      DIRECTORIES:文件夹
         *      ANY:包括此目录下的文件夹、文件
         *  eachFileRecurse:读取此目录和任何子目录中的每个后代文件。
         */
        file2.eachFileRecurse(FileType.FILES, {
                // 局部变量
            directory -> println directory
        })

        def baseDir = "C:\\Users\\12134\\Desktop\\个人进阶之旅\\Groovy"
        try {
            new File(baseDir, 'AB_12.txt').eachLine {
                    // 错误写法,读取不了文件内容
                    //line ->  println(line.text)
                line -> println(line)
            }
        } catch (any) {

        }
        
    }

}
  • Write file

  // 第一种方式
   def file = new File("C:\\Users\\12134\\Desktop\\个人进阶之旅\\Groovy\\user.txt");
   println file.text
   // writer 直接写入文本,会覆盖文件
   file.withWriter('utf-8') {
       writer -> writer.writeLine 'Hello World'
   }

    // 第二种方式
    // 直接调用写入方法
    file.write('abc')

    //第三种方式
    // 更加简便的写法
    file << '''Into the ancient pond
    A frog jumps
    Water’s sound!'''

    //第四种方式
    // append方法追加文本内容
    file.append("名字:李先生\n" + "年龄:21")
    file.eachLine {
        // 文本转换为大写
        println it.toUpperCase()
    }
  •  Other processing

    // 文件内容各行存放到list
    def list = new File(baseDir, 'AB_12.txt').collect { it }
    list.each {
         println it
    }

    new File("C:\\Users\\12134\\Desktop\\个人进阶之旅\\Groovy").traverse { list2 ->
        //如果当前文件是一个目录且名字是mybat,则停止遍历
        if (file2.directory && file2.name == '个人进阶之旅') {
             //否则打印文件名字并继续
             println "mybat" + file2.name
        } else {
             println file2.name
        }
    }


    String message = 'Hello from Groovy'

    // 序列化数据到文件
    file.withDataOutputStream { out ->
        out.writeBoolean(true)
        out.writeUTF(message)
    }
    // 从文件读取数据并反序列化
    file.withDataInputStream { input ->
         assert input.readBoolean() == true
         assert input.readUTF() == message
     }

   // User类实现了Serializable接口
   User p = new User()
   p.setName('Bob')
   // 序列化对象到文件
   file.withObjectOutputStream { out ->
        out.writeObject(p)
   }
   // 从文件读取数据进行反序列化
   file.withObjectInputStream { input ->
        def p2 = input.readObject()
        assert p2.name == p.name
        assert p2.age == p.age
   }

2.1.2 Database processing

 

2.1.3 XML/JSON/Excel processing

 

3.1.1 Unit Test

 

Guess you like

Origin blog.csdn.net/qq_41520636/article/details/109562230