最近因为工作需要,接触groovy,很好的语言。以前学习过python,感觉没有用到的地方,现在用groovy有了深入学习的理由,和java的无缝衔接技术。
?
入门很简单,而且做了一个小脚本,比较几个数据库的表结构,将结果保存在excel中,用groovy代码才不到1K行,使用了POI,derby,oralce数据库等。不用创建很罗嗦的pojo,太好了。
这里就先整理一下基础的groovy东西。全部来自附件文档,然后自己粘贴出来而已。
字符串类型的方法:
?
- def?firstname='Kate'??
- def?surname='Bush'??
- //打印字符串的连接??
- println?firstname*2??
- ??
- def?fullname="$firstname?$surname"??
- println?fullname??
- println?fullname-firstname??
- //凑足15个字符,不够就在左边补充空格??
- println?fullname.padLeft(15)????
- //关于字符串的截取??
- println?fullname[0..3]??
- println?fullname[-4..-1]??
- //下面的方式比较特别,取第5个字符,以及3,2,0)">1位置字符连接起来??
- assert?fullname[5,0)">3..1]=='Beta'??
- ff='aaaabbccadvbasd'??
- lines=ff.split('a')??
- //下面assert在后面表达式为false情况下抛出异常??
- assert?lines.size()==7??
- //注意字符串中的特殊字符??
- def?plain='nrtbf$'??
- assert?plain.size()== //关于字符串的闭包(注意下面的括号的使用方法!)??
- fullname="${->?firstname}?$surname"??
- firstname?=?'li'??
- surname='shuiqing'??
- //关于字符串的运算符??
- fullname?=?fullname?-'qing'-'l'+'?hello?world'??
- assert?fullname=='i?Bush?hello?world'??
- //字符串替换??
- string?=?'hippopotamus'??
- assert?string.replace('ppopotam','bisc')?==?'hibiscus'??
- //字符串反转,转换为list??
- assert'apple'.toList()?==?['a',?'p',?'l',?'e']??
- //下面把字符串里面去掉重复数字,并排序.??
- string?=?"an?apple?a?day"??
- assert?string.toList().unique().sort().join()?==?'?adelnpy'??
- //下面方法取出得到字符串里面的各个单词,并进行反转??
- string?=?'Yoda?said,?"can?you?see?this?"'??
- revwords=?string.split('?').toList().reverse().join('?')??
- assert?revwords==?'this?"?see?you?"can?said,?Yoda'??
- println?revwords??
- //对数组进行筛选,找出反转之后还等于原来字符串并且长度大于5的字符串??
- words?=?['bob',?'alpha',?'rotator',?'omega',?'reviver']??
- bigPalindromes=?words.findAll{w->?w?==?w.reverse()?&&?w.size()?>?5}??
- assert?bigPalindromes==?['rotator',250); line-height:18px"> println?bigPalindromes??
?
数字方法:
def?x=3??
def?y=4??
println?x+y??
println?x.plus(y)??????????????????
println?x?instanceof?Integer???//输出true??
def?a=2/ //进行小数的取三位小数运算.??
def?b?=?a.setScale( assert?b.toString()?==?'0.667'??
//进行不等于的比较??
println?4<=>3?????//输出1??
???4!= ????
4**3??????//4的3次方,等于4.power(3)??
4/3???????//输出1.3333333333,0)">4.div(8.intdiv(3)?????//输出8%3??????????//取余,0)">8.mod(3)??
日期函数:
import?static?java.util.Calendar.getInstance?as?now??
import?org.codehaus.groovy.runtime.TimeCategory??
import?java.text.SimpleDateFormat??
def?date?=?new?Date()+ println?date??
input?=?'1998-06-03'??
df1?=?new?SimpleDateFormat("yyyy-MM-dd")??
date?=?df1.parse(input)??
df2?=?new?SimpleDateFormat("MMM/dd/yyyy")??
println?'Date?was?'+df2.format(date)??
println?now().time??
println??df1.format(now().time)??
//进行时间的计算??
use(TimeCategory){??
????date3?=??new?Date()+1.year+3.hours-2.days??
????println?df1.format(date3)??
}??
/*??
Tue?Apr?10?14:59:33?CST?2012??
Date?was?六月/03/1998??
Mon?Apr?09? 2012-04-09??
2013-07??
*/??
操作符重载:
//下面演示对字符串实现了操作符++的重载.++对应的方法名是next??
?for?(?i='a';i<'d';i++)??
???print?i?+",?"??
???
?println?''??
?????
?for(?i?in?'a'..'d')??
??print?i+",250); line-height:18px"> ??//下面演示的对于集合,重载了操作符<<,对应的方法名是leftShift()??
??lst?=?['hello']??
??lst?<<?'there'??
??println?lst??
??//下面演示对一个自定义类实现的+的重载。??
??class?ComplexNumber{??
??????def?real,imaginary??
????????
??????def?plus(other){??
??????????new?ComplexNumber(real:real+other.real,??
???????????????imaginary:imaginary+other.imaginary)??
??????}??
??????String?toString(){??
??????????"$real?${imaginary>0???'+':''}${imaginary}i"??
??}??
??c1?=?new?ComplexNumber(real:1,imaginary:2)??
??c2?=?new?ComplexNumber(real:4,imaginary:-31)??
??println?c1+c2??
?
操作数据库
import?groovy.sql.Sql??
- def?testYear?=?'2011'??
- //下面的Driver类找不到!修改配置文件就可以了。??
- def?sql?=?Sql.newInstance("jdbc:mysql://localhost:3306/dwz","root","123456"??
- ????,"com.mysql.jdbc.Driver")??
- println?'数据库名:'+sql.connection.catalog??
- ??
- ?????
- sql.execute("delete?from?testtable?where?name?like???or?name?like???or?name?like??",['ls%','lish%','%dataSet%'])???
- println?'插入我的数据之前,数据库:'??
- sql.eachRow("select?*?from?testtable"){??
- ????println?"id?=?${it.id}???year?=?${it.name}??"+it.name??
- }??
- println?'--------------------------------------'??
- wid?=?123??
- wname?=?'lishuiqing'??
- //下面必须使用双引号!??
- sql.execute("insert?into?testtable(id,name)?values?(${wid},${wname})")???
- sql.execute("update?testtable?set?name?=??where?name?=??",['lsq','lishuiqing'])??
- //下面使用预定义参数的查询语句??
- sql.eachRow("select?*?from?testtable?where?name?like??",["%a%"]){??
- println?'下面练习使用dataset'??
- testtable?=?sql.dataSet('testtable')??
- /*def?anycity?=?testtable.findAll{?it.id>1?}??
- anycity.each{??
- ????println?1??
- }*/??
- ???
- 2.times{??
- ????testtable.add(id:it,name:'使用dataSet添加'+it)??
- println?"testtable.getSql():"+testtable.getSql()??
- println?'总行数:'+testtable.rows().size()??
- num?=?0??
- testtable.each{???
- ????//println?it[0]----也可以输出指定位置的元素!!??
- ????num?=?num+ ????println?it.id+",year="+it.name??
- //注意要使用${}输出参数的话,必须使用双引号。。。??
- println?"${num}"??
- println?"下面显示当前数据库的运行实时状态"??
- sql.eachRow("show?status?"){??
- ????//下面在{}里面定义的变量,在外面也找到,也就是作用域是全部的范围!!??
- ????if(it.variable_name=="Uptime")??
- ????????uptime?=?it[1]??
- ????else?if?(it.variable_name?=='Questions')??
- ????????questions?=?it[ println?"数据库运行时间Uptime?for?Database:${uptime}"??
- println?"数据库查询的条目Number?of?Queries:${questions}"??
- println?"每分钟的查询条目Queties?per?Minutes?=?"+Integer.valueOf(questions)/Integer.valueOf(uptime)??
- sql.eachRow("show?status?like?'Com_%'"){??
- ????if(it.variable_name=="Com_insert")??
- ????????insertnum?=?Integer.valueOf(it[1])??
- ????else?if?(it.variable_name?==?"Com_select")??
- ????????selectnum?=?Integer.valueOf(it[ ????else?if?(it.variable_name?==?"Com_update")??
- ????????updatenum?=?Integer.valueOf(it[ println?"查询语句有${selectnum},百分比:"+100*(selectnum/Integer.valueOf(uptime))+"%"??
- println?"插入语句有${insertnum},0)">100*(insertnum/Integer.valueOf(uptime))+"%"??
- println?"更新语句有${updatenum},0)">100*(updatenum/Integer.valueOf(uptime))+"%"??
- println?'下面将数据库里面的值保存到xml文件'??
- bldr?=?new?groovy.xml.MarkupBuilder()??
- bldr.testtable{??
- ????sql.eachRow('select?*?from?testtable'){??
- ????????data(id:it.id,name:it.name)??
- ????}??
- println?bldr.text()??
?集合
List??
assert?[4]?==(1..4)??
//集合是有顺序的!!??
4]?!=[3]??
3]+[1]?==[ //将一个元素添加到已经存在的list中??
3]<<1?==[ //从已有的list中删除元素??
1]-[3]*2?==[ //flatten:扁平的意思??
3]].flatten()?==[3].reverse()==[ //测试两个集合是否有交叉??
3].disjoint([6])??
//intersect:得到两个集合中的交集??
3].intersect([1])?==[ //对集合进行循环处理??
3].collect{it+3}?==[6]??
1].unique().size()==3??
1].count(1)?==2??
4].min()?==4].max()?==4??
4].sum()?==10??
3].sort()?==[4]??
//对集合进行循环处理判断,并返回结果??
3].findAll{it%2==0}?==[2]??
//对集合的迭代??
def?expected?=?['test']??
expected.each{test?->?println?test}??
Map:??
def?map?=?[a:'b': println?map????//[a: println?map.a??
println?map['a']??
println?map.keySet()??//[a,?b]??
map?=?[:]??
map[1]?=?'a';map[2]='b'??
map[true]?=?'p'??
map[false]?=?'q'??
map[null]='x';map['null']?=?'z'??
assert?map?==[1:'a',0)">2:'b',(true):'p',(false):'q',(null):'x'??
'null':'z']??
//下面的例子很有用,对map进行了很快速的循环输出!!??
def?sb?=?new?StringBuffer();??
[3:'c'].each{k,v->sb?<<?"$k:$v,?"}??
//下面是输出字符串??
"$k:$v,250); line-height:18px"> assert?sb.toString()?=='1:a,?2:b,?3:c,?'??
//下面又是一种快速的输出map为字符串形式的方法??
map?=?[3:'c']??
def?string?=?map.collect{k,v?->?"$k:$v"}.join(',?')??
assert?string?==?'1:a,?3:c'????
//下面演示一个对city进行分类的例子??
assert?[??
????[name:'C',city:'London'],??
????[name:'S',250); line-height:18px"> ????[name:'M',city:'LA'],250); line-height:18px"> ????[name:'Z',city:'HK'],250); line-height:18px"> ????[name:'A',city:'HK']??????????
].groupBy{it.city}==[??
????London:[?[name:'C',city:'London']],250); line-height:18px"> ????LA:[?[name:'M',city:'LA']],250); line-height:18px"> ????HK:[?[name:'Z',city:'HK']?,city:'HK']?]??
]??
//map中顺序也是有关系的!顺序不对的map也不相等??
assert?[?[name:'L'],[name:'H']]?!=?[?[name:'H'],city:'L']]??
?闭包
闭包的一个例子:??
import?static?java.lang.Math.*??
//闭包例子 piA?=?{?22/7?}??
piB?=?{?333/106?}??
piC?=?{?355/113?}??
piD?=?{?0.6*(3+sqrt(5))}??
piE?=?{?7?+37/47?+888/83}??
piF?=?{?sqrt(sqrt(2143/22))?}??
//这里就是闭包的实际算法部分。??
howCloseToPI?=?{?abs(it.value()?-?PI)?}??
algorithms?=?['piA':piA,'piB':piB,'piC':piC,'piD':piD,'piE':piE,'piF':piF]???
findBestPI(algorithms)??
def?findBestPI(map){??
????map.entrySet().sort(howCloseToPI).each{??
????????entry?->//下面调用了闭包的函数??
????????def?diff?=?howCloseToPI(entry)??
????????println?"Alorithm?$entry.key?differs?by?$diff"??
doubleNum?=?{num?->num*2}??
println?doubleNum(3)??
//下面的方法定义就是使用了闭包。传入了num,closure,其中closure是函数类型。??
processThenPrint?=?{num,closure->??
??num?=?closure(num);println?"num?is?$num"??
//下面传入了函数名作为第二个参数??
processThenPrint( //下面传入第二个参数是匿名函数??
10){it/ //下面又是一个闭包的例子??
def?houston(Closure??doit){??
???(10..1).each{??
???????count?->?doit(count)???
???}??
houston{?println?it}??
3.times{println?'Hi'}??
0,0)">2].each{number?->?println?number}??
//注意下面的it!!??
5].each{?println?it}??
def?println?=?{println?it}??
6].each?println??
map?=?['a': map.each{key,value?->?map[key]=value*2?}??
assert?map?==?['a': //注意下面的each后面是小括号,不是大括号了!??
doubler?=?{key,value?->?map[key]?=?value* map.each(doubler)??
8]??
def?doubleMethod(entry){??
????map[entry.key]?=?entry.value?*2;??
doubler?=?this.&doubleMethod??
8,0)">16]??
//下面对集合的一些操作很容易的结合了闭包方法的使用??
//查询子元素??
3].grep{it< //判断是否有一个满足条件??
3].any{?it%0?}??
//判断是否全部满足条件??
3].every{?it?<4}??
//将集合中全部元素join??
assert?(9).collect{it}.join()?==?'123456789'??
4).collect{it*2}.join()?==?'2468'??
5:新的函数curry!以及演示一个通过闭包将list进行修改的例子!!??
def?add?=?{x,y?->?x+y}??
def?mult?=?{x,y?->?x*y}??
assert?add(3)?==? assert?mult( def?min?=?{x,y?->?[x,y].min()}??
def?max?=?{x,y].max()}??
def?sub?=?{x,y?->?return?'x?-?y?=?'+(x-y)}??
//注意下面的curry函数,意思是默认的传入参数到原有的函数的第一个位置,并将结果返回为一个新的函数??
//例如下面的triple就是得到一个数值的三倍!!??
def?triple?=?mult.curry(3);assert?triple(2)?==6??
def?atLeastTen?=?max.curry(10)??
def?subTen?=?sub.curry( assert?atLeastTen(5)==15)?==?15??
assert?subTen(13)?==?'x?-?y?=?-3'??
//??
def?pairWise(list?,invoke){??
????if(list.size()<2)?return?[]??
????def?next?=?invoke(list[0],list[ ????return?[next]+pairWise(list[1..-1],invoke)??
assert?pairWise(7,0)">9]??
6,0)">12,0)">20]??
5]??
//inject--参数是初始值,然后放在一个闭包里面对list的每个元素进行迭代操作!??
assert?'cbaxabc'?==?['a','b','c'].inject('x'){??
????result,item?->?item?+result+item??
}??
?对xml的操作
对xml的解析??
def?CAR_RECORDS?=?'''??
<records>??
<car?name='HSV?Maloo'?make='Holden'?year='2006'>??
<country>Australia</country>??
<record?type='speed'>Production?Pickup?Truck?with?speed?of?271kph</record>??
</car>??
<car?name='P50'?make='Peel'?year='1962'>??
<country>Isle?of?Man</country>??
<record?type='size'>Smallest?Street-Legal?Car?at?99cm?wide?and?59?kg?in?weight</record>??
<car?name='Royale'?make='Bugatti'?year='1931'>??
<country>France</country>??
<record?type='price'>Most?Valuable?Car?at?$15?million</record>??
</records>??
'''??
//解析xml的第一步,进行分析--注意这里的找到的是根节点<records>,所以后面的car。size()就有值。??
def?records?=?new?XmlSlurper().parseText(CAR_RECORDS)??
//得到节点的数目??
assert?3?==?records.car.size()??
//注意下面的得到car里面的country的条目,而不是直接进行records.country!!??
3?==?records.car.country.size()??
//depthFirst():计算全部的节点的数目?????
10?==?records.depthFirst().collect{it}.size()??
def?firstRecord?=?records.car[0]??
//得到一个节点里面的属性name??
assert?'car'?==?firstRecord.name()??
//得到一个节点里面的自定义属性,使用@属性名???
assert?'Holden'?==?firstRecord.@make.toString()??
//text():得到节点里面的文本信息!不是属性。??
assert?'Australia'?==?firstRecord.country.text()??
//对节点进行判断,找到make属性含有e的条目数量??
2?==?records.car.findAll?{it.@make.toString().contains('e')}.size()??
//使用正则表达式进行节点筛选??
2?==?records.car.findAll{it.@make=~'.*e.*'}.size()??
//找到全部的国家符合正则表达式的record节点的make属性!??
assert?['Holden','Peel']?==?records.car.findAll{?it.country?=~?'.*s.*a.*'}??
????.@make.collect{it.toString()}??
??????
//找到全部的type非空的record节点的type属性!!??
assert?['speed','size','price']?==?records.depthFirst().grep{it.@type!=''}.'@type'*.toString()??
def?countryOne?=?records.car[1].country??
//查找父节点的两个方法!parent和使用路径表达式??
assert?'Peel'?==?countryOne.parent().@make.toString()??
assert?'Peel'?==?countryOne.'..'.@make.toString()??
//将所有的节点按照指定顺序排序之后,再按顺序输出name属性!注意后面的一个×号!??
def?names?=?records.car.list().sort{?it.@year.toInteger()}.'@name'*.toString()??
assert?['Royale','P50','HSV?Maloo']?==?names??
?操作文件,属性文件:
myFileDir?=?"d:"??
myFileName?=?'mytest.txt'??
myFile?=?new?File(myFileDir?+?myFileName)??
printFileLine?=?{?println?"File?line:"+it}??
myFile.eachLine?(?printFileLine?)??
myFile.write('123')??
myFile.append('123')??
读取属性文件:??
Properties?properties?=?new?Properties()??
properties.load(new?FileInputStream("d:conf.properties"))??
println?properties.getProperty("filename")??
?正则表达式:
正则表达式:??
assert?'Hello?World!'?=~?/Hello/??
assert?'Hello?World!'?==~?/Hellob.*/??
def?p?=?~/Hellob.*/??
assert?p.class.name?==?'java.util.regex.Pattern'??
//下面的next方法是返回的下一个字符!??
assert?"1.23".replaceAll(/./){ch->?ch.next()}==?"2/34"??
assert?"1.23".replaceAll(/d/){num?->?num.toInteger()+1}=='2.34'??
//下面的?==?不可以换行!否则就是语法错误!!为什么??因为每一行后面默认就是有一个分号的!!??
assert?"1.23".replaceAll(/d+/){num?-
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|