前言
某年某月某日,正式从python转移到groovy.关于python和groovy的比较,网上已经有许多文章了.我的理由是, 作为一个上了年纪的java程序员,groovy的学习曲线要比python低.毕竟,我只是想用groovy写一些小程序.而这些小程序用java做又太耗时间.
希望这篇文章能够帮助java程序员尽快进入groovy世界.
预备知识,安装
学习groovy最好能熟练用java,有一点javascript经验.熟悉ant更好.
到官方主页
http://groovy.codehaus.org/ 下载二进制包或源码包进行安装. 温馨提示Ubuntu用户,不要安装源里面的groovy. 下载官方源码包, 设置好java路径和ant路径,运行源码包里的build脚本即可安装groovy.
在上面还可以下载到eclipse插件,不再赘述.
1 groovyConsole和helloworld
在groovy安装目录的bin文件夹下,有一个groovyConsole.sh(windows是groovyConsole.exe), 它就是自带的简易groovy程序编辑器. 打开它,输入如下代码:
def str1 = "Hello,world.";
println(str1)
String str2 = "Hello,Groovy.";
println(str2)
str3 = "Hello,variables.";
println(str3)
def age1 = 30;
println("You age: "+age1);
age2 = 31;
println("You age: "+age2);
def s = """
知识点:
1>可以用多种方式定义变量
2>如何在控制台输出文本
3>如何方便的显示多行文本
"""
println(s);
保存文件,快捷键ctrl+R, 恭喜你,第一个groovy程序运行成功.
2 如何定义函数
def func(a,b){
println("Your name is: "+a+" and your age is: " + b);
}
func("Diego",30)
def func1(a,b=25){
if(b==null){
println("Your name is: "+a+" and your age is a secret");
}else{
println("Your name is: "+a+" and your age is: " + b);
}
}
func1("Diego")
func1("Diego",30)
func1("Diego",null)
/**
知识点:
1>如何定义和函数
2>如何在函数里定义默认参数
**/
3 字符串使用
def country="南非"
def stringTemplate(country){
return "${country}世界杯来了";
}
def s = stringTemplate(country);
println(s+",length: "+s.length());
println("Country is: "+s[0,2]);
println("Country is: "+s.substring(0,2));
def greetingWithFormat = """
欢迎来到${country}
6.11-7.11, 世界杯将会激情展开!
""";
println(greetingWithFormat);
/**
知识点:
1>模板式字符串,这是个很好很强大的功能.
2>如何多段式风格字符串.
3>如何用groovy的风格完成substring功能.
4>中文字符串长度
**/
4 List的使用
def myrange = 25 .. 10
println(myrange);
myrange = 11 .. 19
println(myrange);
println("First element of collection is: "+myrange[0]);
//myrange<<</span>20;//This statement will cause exception.
println("Last element of collection is: "+myrange[-1]);
println("Sub collection: " + myrange[2,5]);
println("Reverse: " + myrange.reverse());
println("Remove element: " + (myrange - 18));
println("Remove sub collection: " + (myrange - [12,13,14,15]));
//==================
def coll = ["C","C++","Java","JavaScript","Python"]
println("Program anguages you're knowing: "+coll);
coll <<</span> "Groovy" // It's == coll.add("Groovy")
println("Now you're learning: " + coll[-1])
//cool syntax
coll = coll*.toUpperCase()
println(coll);
/**
知识点:
1>如何方便定义collection
2>collection的各种操作
3>注意groovy重载了+和-运算符. 所以collection可以很方便的用+和-删除元素. 在这样做的时候, 最好加上().
4>*是很酷的一个功能, 方便的遍历集合元素.
**/
5 方便的for循环
//For statement
def forFunc(a,repeat=10){
for(i=a;irepeat;i++){
print(i+",");
}
}
def forFunc1(a,repeat=10){
for(i in a .. repeat){
print(i+",");
}
}
forFunc(2);
println();
forFunc1(2);
/**
知识点:
1>两种循环风格.
2>a .. repeat 这种风格等价于 i=a;i<=repeat;i++
**/
6 方便的for循环
//For statement
def forFunc(a,repeat=10){
for(i=a;irepeat;i++){
print(i+",");
}
}
def forFunc1(a,repeat=10){
for(i in a .. repeat){
print(i+",");
}
}
forFunc(2);
println();
forFunc1(2);
/**
知识点:
1>两种循环风格.
2>a .. repeat 这种风格等价于 i=a;i<=repeat;i++
**/
7 map的用法
def mymap = ["name":"Diego",age:30,hobbies:["Football","Reading","Bible"]]
println("Your name is "+ mymap["name"] +" ,age is "+mymap["age"]+" ,hobbies: " + mymap["hobbies"]);
//add element
mymap.location = "Shenzhen"
println(mymap);
//loop map by closure.
mymap.each{key,value->
println("Key: "+key+",value: "+value);
}
/**
知识点:
1>如何使用map
2>如何遍历map
**/
8 closure的用法
//Traditional looping collection.
def mydata = ["Java","Groovy","JavaScript"]
def printUpperCase(a){
println(a.toUpperCase());
}
for (i in 0..2){
printUpperCase(mydata[i]);
}
println("use closure=====================");
mydata.each{
println(it.toUpperCase());
}
println("def closure=====================");
def myclosure = {myvar->
println(myvar.toUpperCase());
}
mydata.each(myclosure);
println("closure and map=====================");
def mymap = ["name":"Diego",age:30,hobbies:["Football","Reading","Bible"]]
mymap.each{key,value->
println("key is: "+key+" and value is: " + value);
}
println("closure and string=====================");
def mystring= "Diego"
mystring.each{s->
print(s+",");
}
/**
知识点:
1>闭包(closure)的直观例子
2>如果没有特别声明, 闭包将用it作为变量名字
3>如何定义和调用闭包,如何在闭包自定义变量名字
**/
9 文件操作
BufferedReader reader = new File('f:/abc.txt').newReader('GBK')
BufferedWriter writer = new File('f:/abc.csv').newWriter('UTF-8')
reader.eachLine { line ->
if(line && line[0] != '#') {
writer.writeLine(line)
}
}
writer.close()
def createFile(path,createIfNotExist){
def file = new File(path);
if( !file.exists() ){
if(createIfNotExist){
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
file.createNewFile();
}else{
throw NullPointerException("Missing file: "+path);
}
}
return file;
}
def copyFile(String frompath,String topath,boolean createDestIfNotExist){
def fromfile = new File(frompath);
if( !fromfile.exists()){
println(" ###################Missing file: " + fromfile+"\n");
return false;
}else{
println(" Copying file: " + frompath+"\n");
}
def tofile = createFile(topath,createDestIfNotExist);
tofile.withWriter { file ->
fromfile.eachLine { line ->
file.writeLine(line)
}
}
return true;
}
/**
知识点
1>如何读写文件
2>groovy的文件操作
**/
10 读写xml
特别提示: 根据自己的实际情况修改文件路径.
def sample ="""
We'll create this xml:
"""
println(sample);
//写xml
testxml = "g:/download/test.xml";
import groovy.xml.MarkupBuilder
xml = new MarkupBuilder(new FileWriter(testxml));
xml.beans{
bean(id:"myBean1",class:"com.diegochen.Bean1"){
property(name:"dao",ref:"dao1")
}
bean(id:"myBean2",class:"com.diegochen.Bean2"){
property(name:"dao",ref:"dao2")
}
}
println("Done creation. Now reading xml\n")
//Read xml
start =System.currentTimeMillis();//传说XmlParser吃内存,XmlSlurper速度慢
def node = new XmlParser().parse(new File(testxml))
println("node name:"+node.name());//取得node的名字.为什么不是getname()???? 命名规则真混乱
end =System.currentTimeMillis();
println("elapsed time: "+ (end-start)+" ms");
/**
node = new XmlSlurper().parse(new File(testxml))
println("node name:"+node.name());
end =System.currentTimeMillis();
println("elapsed time: "+ (end-start)+" ms");
**/
//访问子节点和属性
println("How many beans?: "+node.children().size());
def bean2 = node.children()[1];
println("2nd bean's id: "+bean2."@id");
println("2nd bean's class: "+bean2."@class");
println("2nd bean's dao property: "+bean2.children()[0]."@ref");
/**
知识点:
1>怎样生成xml
2>怎样读xml
**/
11 读配置文件
先创建一个名为config.gy的配置文件. 内容如下:
path{
//This is file update list txt path. The file should contain a batch of file path.
file_update_list = "e:/work/cc2/file_update_list.txt";
//This is root directory of workspace
workspace_root_path = "e:/work/cc2/asia_stratagy/workspace";
//This is directory for backup.
backup_path = "d:/download";
}
//Don't modify below config!!!
constants{
debug = "Y"
}
然后在另一个groovy文件里如此访问
def propfile = "${System.properties['user.dir']}/config.gy";
println("--config file: "+propfile);
def config = new ConfigSlurper().parse( new File( propfile ).toURL()) ;
def fileUpdateList = config.path.file_update_list;
def workspace_root_path = config.path.workspace_root_path;
def backup_path = config.path.backup_path;
def debugFlag = config.constants.debug;
if(debugFlag == "Y"){
println("config:==[fileUpdateList] : "+ fileUpdateList );
println("config:==[workspace_root_path] : "+ workspace_root_path );
println("config:==[backup_path] : "+ backup_path );
println("config:==[debugFlag] : "+ debugFlag );
}