Groovy基础篇

来源:互联网 发布:网络新词 四个字2016 编辑:程序博客网 时间:2024/05/22 00:18

首先,了解一下什么是Groovy:

·它是一种像Java一样运行在JVM上,但更加敏捷的动态语言。·它的语法理念源于Python,Ruby和Smalltalk,但它的语法与Java语言的语法很是相似。·相比于Java,大大减少了代码量,让人更加容易阅读和维护,提高了开发效率·Groovy无缝的集成了Java现有的所有的类和库,直接编译成Java字节码,因此可以和Java很好的结合利用。·简化了测试,支持单元测试,具有开箱即用的功能。

有Java基础的,对于学习Groovy是没有任何障碍的,需要在实际应用中,不断融入自己的代码中,提高效率,接下学习Groovy

最简单的例子来看看Groovy语法的简练(对比Java)

在Java中,输出“hello world”代码如下:
public class HelloWorld {    public static void main(String[] args) {        // TODO Auto-generated method stub        System.out.println("hello world ");    }}       结果:hello world

而用Groovy,输出“hello world”代码如下:

println "hello world"      结果:hello world

若是仅需要达到输出功能,则不需要定义类和main方法,只需一句输出语句,也不需要System.out和括号,就可以达到同样的效果,是不是相当简练!

接下来详细看一下Groovy的一些语法特点:
1.在声明一个变量时,groovy 不要求强制类型声明 ,仅仅要求变量名前使用关键字def(在方法参数和循环声明中不需要) 如下:

class Test1 {    static main(args) {        def var1  = "hello"        def var2 = 123        def var3 = true        println var1        println var1.class        println var2        println var2.class        println var3        println var3.class    }}结果:helloclass java.lang.String123class java.lang.Integertrueclass java.lang.Boolean

可以看出,虽然没有声明变量类型,但是Groovy还是可以自动的识别变量的类型,这是因为在Groovy中,所都的变量都被当做对象对待,举个例子:将上面main中的代码修改如下

    def var1  = "hello"        println var1        println var1.class        var1 = 123        println var1        println var1.class        结果为:helloclass java.lang.String123class java.lang.Integer

说明,同一个变量,在运行中赋予不同的类型,则它就会动态的改变,即它一直以对象的状态存在,随时可以发生变化。
2. Groovy中默认的修饰符为public,因此在main方法面不需要public修饰,在上面的例子中,并没有写public,效果还是一样的。
3. 每句代码后面“;”是可选的,如果同一行有俩句语句,则用“;”分割,否则并不需要,上面的代码中可以看出,只需换行就ok了。
4. 用Groovy写循环语句时,也会简单很多,同一个循环语句,用Java编写如下:

public class SayHello {    public static void main(String[] args) {    for(int i=0;i<5;i++){        System.out.println("hello");    }    }}结果:hellohellohellohellohello

而用Groovy代码如下:

    def repeat(){        for(i=0;i<5;i++){            println "hello"        }    }    repeat()    结果:    hello    hello    hello    hello    hello

对比一下发现,在Groovy循环中,不需要在循环变量前加def,也不需要对 i 指定数据类型 int
把循环继续修改为如下:

for(i in 0..4){            println "hello"        }        结果:hellohellohellohellohello

效果是一样的,但是显得更加简练。这里的 0..4 涉及到了关于Groovy中的范围的概念:
范围是一系列的值,如0..4代表0 1 2 3 4 ,a..d代表a b c d,于此同时,它也支持排除范围,如0..<4表示0 1 2 3 即不包含4,a..

    def repeat(val,repeat=5){        for(i in 0..<repeat){            println val        }    }    repeat("hello",2)    repeat("world",3)    repeat("repeat")    结果:hellohelloworldworldworldrepeatrepeatrepeatrepeatrepeat  

可以看出,若不指定循环次数,则会调用默认值,即输出5次“repeat”。

5.关于Groovy中的集合,这是Groovy相比较于Java很是突出的一部分,它能够很方便的操作集合。因为在Groovy中,集合是以内置的方式存在,不需要像在Java中一样,导入专门的类然后初始化,而是可以直接进行定义以及对数据的添加删除等操作。看一个例子:使用Java,对一个集合进行操作,如下:

import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class Filter {    public static void main(String[] args) {        List list = new ArrayList();        list.add("Rod");        list.add("Neeta");        list.add("Eric");        list.add("Missy");        Filter filter = new Filter();        List shorts = filter.filterLongerThan(list, 4);        System.out.println(shorts.size());        Iterator iter = shorts.iterator();        while (iter.hasNext()) {            System.out.println(iter.next());        }    }    public List filterLongerThan(List list, int length) {        List result = new ArrayList();        Iterator iter = list.iterator();        while (iter.hasNext()) {            String item = (String) iter.next();            if (item.length() <= length) {                result.add(item);            }        }        return result;    }}结果:2RodEric

而使用Groovy,代码如下:

def list = ["Rod", "Neeta", "Eric", "Missy"]//定义一个集合并将数据放入集合中def shorts = list.findAll { it.size() <= 4 }//定义一个集合,并对集合直接进行操作println shorts.size()//输出所需要的结果shorts.each { println it }//遍历集合结果:2RodEric

对比可以看出,在Java中,需要导入专门的类,需要进行初始化,需要使用add()方法进行对数据的添加,在取出数据时,还需用到迭代器取出,而使用Groovy的时候,可以直接定义一个集合,将数据直接放入其中。
在对数据进行操作时,可以用到一下方法:

例如给上面的list中添加数据,

def list = ["Rod", "Neeta", "Eric", "Missy"]//定义一个集合并将数据放入集合中list.add("Harry")//add()方法  list<<"hey"//操作符重载方式添加list[6] = 'Ide'//根据位置来添加,注意如果覆盖了原有位置,则会覆盖对应的数据结果:[Rod, Neeta, Eric, Missy, Harry, hey, Ide]

检索某一项数据:

assert list[1] == "Neeta"//检测正确性,若正确,则程序继续运行,否则将中断并报详细错误结果:[Rod, Neeta, Eric, Missy, Harry, hey, Ide]//说明上面取出的数据是正确的
这是一个错误的例子:def list2 = [1,2,3]assert list2[1] == 1//the right is 2println list2结果:Caught: Assertion failed: assert list2[1] == 1       |    |   |       |    2   false       [1, 2, 3]

细心一点还会发现一个问题:在上面的代码assert list[1] == "Neeta"
中,对于String类型的判断,用的居然是“==”,而且还是正确的结果,这里,其实还是Groovy中的关于一切变量都是对象的实现,表面上看是“==”,但在底层实际上已经重现了这个方法,用的还是equals方法。
6.关于Groovy中的映射,Java 语言中的映射是名称-值对的集合。所以,要用 Java 代码创建典型的映射,必须像下面这样操作:

Map<String,String> map = new HashMap<String,String>();map.put("key1","hello");map.put("key2","world");

而使用Groovy处理映射的操作如下:

def map = [key1:"hello",key2:"world"]

当我们需要对集合进行迭代时,可以用如下方法:

map.each {    println it}结果:key1=hellokey2=world

这里涉及到关于Groovy中的闭包,它的形式为:“{”代码“}”,即一个大括号,中间加代码。在上面的each后的内容,即为一个闭包的形式,”it”是一个关键字,它指向被调用集合外部的每个值,它是一个默认值。我们可以改变它:

def map = [key1:"hello",key2:"world"]map.each { values-> //将默认it用values替代    println values}结果:key1=hellokey2=world

以上是对默认参数和一个参数的迭代,再来看一下多个参数的的迭代:

def map = [key1:"hello",key2:"world"]map.each {key,values->      //俩个参数    println "${key},${values}"    }结果:key1,hellokey2,world

可以看出,使用“${参数…}”的方式,可以对多个参数进行迭代。

在上面的代码中,还有一点值得注意,在输出语句中,如果将println "${key},${values}"中的双引号改为单引号,结果如下:

${key},${values}${key},${values}

这里可以说明,在虽然单引号和双引号在输出一句话的时候可以随便使用,但涉及到调用表达式的时候,则必须使用双引号。
7.关于Groovy中的类定义和Java的基本相似,它的方法可以基于类(static)或者实类,可以为public,protect,private,支持常用的Java修饰符,比如synchronized,但它的缺省是public,所以我们在定义时,并不需要写public,它的方法的参数的类型不是强制性的,这点和Java不同。先看一个最简单的类的定义:

class Employee {    def id    def name    def salary    def display(){        println  "ID:${id},Name:${name},Salary:${salary}"    }}   创建对象并调用方法:def employees = new Employee(id:1,name:'jor',salary:1000)employees.display()结果:ID:1,Name:jor,Salary:1000如果是这样进行创建实类对象:def employees = new Employee()employees.display()同样可以通过,结果为:ID:null,Name:null,Salary:null

可以看出,在上面的类中并没有定义它的构造方法,相当于Groovy提供了默认的构造方法,所以在创建对象时,即使是空的对象参数,依旧可以创建,其值为null,当然也可以显式的定义构造方法:

class Employee {    def id    def name    def salary    def Employee(id,name,salary){        this.id = id        this.name = name        this.salary = salary    }    def display(){        println  "ID:${id},Name:${name},Salary:${salary}"    }}   创建实类:def employees = new Employee(1,'jor',1000)employees.display()结果:ID:1,Name:jor,Salary:1000如果按上面的第二种方式继续创建一个实类:def employees = new Employee()则会报错

def employees = new Employee(id:1,name:'jor',salary:1000)

这样的方式来创建对象更加灵活,这时不需要自定义构造方法。
将上面的类修改如下:

class Employee {    def id    def name    def salary    String toString(){        return  "${id},${name},${salary}"    }}结合集合同时创建多个对象:def employees = [    new Employee(id:1,name:'hell',salary:5000),    new Employee(id:2,name:'sili',salary:4000),    new Employee(id:3,name:'mald',salary:7000)]employees.each{employee->println employee}结果:1,hell,50002,sili,40003,mald,7000

这里利用重写 toString 方法结合前面的集合及闭包,很容易实现对多个对象的创建及输出。

8.关于Groovy中的安全导航操作符:(?.),当程序进行判断操作的时候,可以很好的减少条件语句,例如:

def foo(str){    if(str!=null) {return str.reverse()}}println foo("hello")结果:olleh

替换后如下:

def foo(str){    str?.reverse()}println foo("hello")结果:olleh

9.关于Groovy的结构,和Java中基本类似,包含判断语句if..else,switch,三元操作符,循环语句for,while,(do…while不支持),以及continue和break给个例子:

def val = 'a';while(val++<'e'){    if(val=='b'){        println val    }else{    println val+'s'}}结果:bcsdses

switch语句在Groovy中比较强大,它可以匹配任何类型的值,例如:

 v = 2switch(v){    case Number:println "choosed number";    case ~"\\.+\\.":println "choosed matchRegex";    case [1,1,1,1] :println "choosed List";}结果:choosed numberchoosed matchRegexchoosed List

解释一下,本来应该每句的末尾加break的,但为了验证它的功能,将后面的也都执行了一次。
10.关于Groovy中的Boolean,它和Java中的Boolean类型的用法还是有很大的区别,例如,在Java中:

int val = 1;ifval){System.out.println("true");}结果错误的,因为if中必须得判断表达式才可以

而在Groovy中,

def val = 1if (val){     println "true"}结果:true

说明将一个对象放在一个boolean表达式中,Groovy会自动检测这个对象是否为null,如果为null,则返回false,否则为true。下面列出了在不同的类型中Boolean值的判定规则:

类型 为true的条件 Boolean true Collection 不为空 Character 值不为 0 CharSequence 长度> 0 Enumeration 有更多元素 Iterator 有文件 Number 双精度值不为0 Map 不为空 Matcher 至少一个匹配 Object[ ] 长度> 0 任何其他类型 引用不为 null

11.关于Groovy中简单的文件操作:

读取指定文件内容:File file = new File('E:/test1.txt')file.eachLine {lines->    println lines }结果:helloworldhaha按指定格式读取:file.eachLine("utf8") {println it  } 
向文件中写入内容:file.append('0.0.0.0.')  file.eachLine {println it }结果:hello,harry,dd,dd,f,g,hworld is beautiful,isn't it?byby0.0.0.0.

直接就可以操作,用不着关心关于流,异常控制,资源关闭等操作,Groovy搞定了这些,是很简练吧。

12.关于Groovy中简单的正则表达式应用:

def str='abcdefg'assert str=~'abc'运行正确,说明在用“=~”只要字符串是被匹配字符串的子串,表达式就是正确的。----------def str='abcdefg'assert str==~'abc'结果:Caught: Assertion failed: assert str==~'abc'       |  |       |  false       abcdefg说明“==~”为精确匹配,只有完全相同时,才正确。

13.关于Groovy中的单元测试:
首先将JUnit导入Eclipse项目中:

这里写图片描述

选择JUnit4,完成后项目下会出现包:

这里写图片描述

然后新建一个测试类:选择你要测试的项目–>new一个JUnit test case–>填写测试类名,包名及所要测试的类–>完成,编写测试方法进行测试。

0 0