首先,了解一下什么是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 } } 结果: hello class java.lang.String 123 class java.lang.Integer true class java.lang.Boolean可以看出,虽然没有声明变量类型,但是Groovy还是可以自动的识别变量的类型,这是因为在Groovy中,所都的变量都被当做对象对待,举个例子:将上面main中的代码修改如下
def var1 = "hello" println var1 println var1.class var1 = 123 println var1 println var1.class 结果为: hello class java.lang.String 123 class 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"); } } } 结果: hello hello hello hello hello而用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" } 结果: hello hello hello hello hello效果是一样的,但是显得更加简练。这里的 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") 结果: hello hello world world world repeat repeat repeat repeat repeat可以看出,若不指定循环次数,则会调用默认值,即输出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; } } 结果: 2 Rod Eric而使用Groovy,代码如下:
def list = ["Rod", "Neeta", "Eric", "Missy"]//定义一个集合并将数据放入集合中 def shorts = list.findAll { it.size() <= 4 }//定义一个集合,并对集合直接进行操作 println shorts.size()//输出所需要的结果 shorts.each { println it }//遍历集合 结果: 2 Rod Eric对比可以看出,在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 2 println 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=hello key2=world这里涉及到关于Groovy中的闭包,它的形式为:“{”代码“}”,即一个大括号,中间加代码。在上面的each后的内容,即为一个闭包的形式,”it”是一个关键字,它指向被调用集合外部的每个值,它是一个默认值。我们可以改变它:
def map = [key1:"hello",key2:"world"] map.each { values-> //将默认it用values替代 println values } 结果: key1=hello key2=world以上是对默认参数和一个参数的迭代,再来看一下多个参数的的迭代:
def map = [key1:"hello",key2:"world"] map.each {key,values-> //俩个参数 println "${key},${values}" } 结果: key1,hello key2,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,5000 2,sili,4000 3,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") 结果: olleh9.关于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'} } 结果: b cs ds esswitch语句在Groovy中比较强大,它可以匹配任何类型的值,例如:
v = 2 switch(v){ case Number:println "choosed number"; case ~"\\.+\\.":println "choosed matchRegex"; case [1,1,1,1] :println "choosed List"; } 结果: choosed number choosed matchRegex choosed List解释一下,本来应该每句的末尾加break的,但为了验证它的功能,将后面的也都执行了一次。
10.关于Groovy中的Boolean,它和Java中的Boolean类型的用法还是有很大的区别,例如,在Java中:
int val = 1; if(val){ System.out.println("true"); } 结果错误的,因为if中必须得判断表达式才可以而在Groovy中,
def val = 1 if (val){ println "true" } 结果: true说明将一个对象放在一个boolean表达式中,Groovy会自动检测这个对象是否为null,如果为null,则返回false,否则为true。下面列出了在不同的类型中Boolean值的判定规则:
类型为true的条件BooleantrueCollection不为空Character值不为 0CharSequence长度> 0Enumeration有更多元素Iterator有文件Number双精度值不为0Map不为空Matcher至少一个匹配Object[ ]长度> 0任何其他类型引用不为 null11.关于Groovy中简单的文件操作:
读取指定文件内容: File file = new File('E:/test1.txt') file.eachLine {lines-> println lines } 结果: hello world haha 按指定格式读取: file.eachLine("utf8") {println it } 向文件中写入内容: file.append('0.0.0.0.') file.eachLine {println it } 结果: hello,harry,dd,dd,f,g,h world is beautiful,isn't it? byby 0.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–>填写测试类名,包名及所要测试的类–>完成,编写测试方法进行测试。