1. 正则表达式:
正则表达式在Groovy中是本地语言级别的支持
def aRegex=~'lxt' ~开头的表示一种模式 println aRegex.class//输出:class java.util.regex.Pattern def mat='lxt'=~'lxt' println mat.class //class java.util.regex.Matcher//~开头的字符串是模式Pattern对象 assert 'lxt008'=~'lxt'//true部分匹配用= assert !('lxt008' ==~'lxt')//true精确匹配用==
正则表达式元字符:
.匹配任意单个字符
^匹配行的开始部分
$匹配行的结尾部分
*匹配*前字符或正则表达式出现0或多次
+匹配+前字符或正则表达式出现1或多次
?匹配?前字符或正则表达式出现0或1次
[]匹配[]中字符集中任一字符
{}限定前面的字符或正则表达式出现的次数 assert !('lxxxxx8'==~'l[a-z0-9]{1,4}8')//最少1个最多4个
\转义符 assert '$'==~'\\$'
|"或"选择符(几个中只能选择其中之一)
()将封装的表达式组合起来
正则表达式的辅助符号:
辅助符号等价符号描述
\d[0-9]数字
\D[^0-9]非数字
\w[a-zA-Z0-9]word字符
\W[^a-zA-Z0-9]非word字符
\s[\t\n\f\r\v]空白字符
\S[^\t\n\f\r\v]非空白字符
在Java与Groovy中把“\”作为转义符会有冲突,所以一般使用“\\”表示转义字符
assert '1.2' == ~"\\d\\.\\d" assert "1 a"==~"\\d\\s\\w" def detePattern ="([A-Z]{3})\\s([0-9]{1,2}),\\s([0-9]{4})" def date="NOV 28, 2008" def matcher = date =~datePattern matcher.matches() assert date=~datePattern//true println matcher[0]//["NOV 28, 2008","NOV","28","2008"] println matcher[0][0]//NOV 28,2008 println matcher[0][1]//NOV println matcher[0][2]//28 println matcher[0][3]//2008
2. 闭包:
由{}包围起来的代码块就是闭包。
println{}//执行如果为:输出类似于类$匿名内部类@hash code
结论一:闭包就是一个匿名内部类
也可以给闭包起名字:
def aClosure={
prinltn "hello Closure!"
}
2.1调用闭包
aClosure.call()//使用call()调用闭包
aClosure()//调用闭包的简写方式,类似与方法调用
结论二:闭包是一个可执行的代码块
闭包在调用的时候才会执行
2.2参数化闭包:
def bClosure={ println "Hello ${it}!"//用$引用参数 } bClosure.call("lxt008") bClosure('lxt008') bClosure 'lxt008'//结果输出三个:Hello lxt008
it是闭包的单个隐含参数
闭包使用显式参数
def cClosure ={name,address->
println "${name},${address}!"
}
调用cClosure('lxt008','shenzhen')
闭包支持默认参数
def dClosure={name,address="shenzhen"->
println "${name},${address}"
}
调用dClosure('lxt008')//输出:lxt008,shenzhen!
2.3闭包作用域:
def name="lxt008"
def eClosure = { println name}
eClosuer()//输出:lxt008
//闭包可以作为方法的参数
def aMethod(Closure closure){
name = "lxt007";closure()
}
aMethod(eClosure)//???输出:lxt008闭包访问的变量是全局的不能是局部变量
def fClosure={
name="lxt006";eClosure()
}
fClosure()//输出:lxt006闭包中定义的是全局变量相当于修改了前面的值
闭包可以返回值:
def gClosure={number ->
return number*2
}
println gClosure(3)
闭包返回6,其中return可以省略,因为它会返回最后一行代码执行的结果
2.4闭包与集合,字符串
闭包在Groovy中频繁出现,但最常用于对一系列值上迭代,如列表、映射,范围,String,File
闭包可以用更简洁的方式对集合进行迭代,已经不需要Java的迭代器了。
用each遍历list:
def citysList=["s",'b','s'] citysList.each{ print city+'' } 输出:s b s
遍历Map:
def citysMap=[1:'shenzhen',2:'beijing',3:'shanghai'] citysMap.each{city-> print city.key+" "+city.value+" " }//输出1 shenzhen 2 beijing 3 shanghai 遍历Range: (1..<5).each{print it +'-'}//输出:1-2-3-4- 遍历GString 'lxt008'.each{print it+'-'}//输出:l-x-t-0-0-8-
闭包为参数的迭代集合的方法:
boolean any(Closure clos)
有一个集合元素满足闭包条件则返回true
List collect(Closuer clos)
把集合每个元素用闭包转换后返回列表
List collect(Collection coll,Closure clos)
把集合每个元素用闭包转换后入到coll中
bollean every(Closure clos)
判断是否每个元素都满足闭包条件
Object find(Closure clos)
从集合中找到满足闭包条件的第一个元素
List findAll(Clouse clos)
从集合中找到满足闭包条件的所有元素
int findIndexOf(Clouse clos)
从集合中找到满足闭包条件的第一个元素的索引
Object inject(Object value,Closure clos)
value 与第一个元素传给闭包,结果值第二个集合元素又传给闭包,类推
void reverseEach(Clousre clos)
反射迭代
List sort(Closure clos)
排序集合
2.5 闭包的其他特性:
闭包可以嵌套定义:
def outerClosure={
println coutry
//嵌套定义闭包,方法则不允许
def innerClosure={city->
println city
}
innerClosure('shenzhen')
}
outerClosure("china")//先打印china,后打印shenzhen
把流程控制语句重构为闭包可以提高项目维护性
3 Groovy类例子:
class Toy{ def toyName def unitPrice def method(){ println "Invoke method" } String toString(){"${toyName}"} } def toy = new Toy(toyName:'toy1',unitPrice:'100') println 'Toy ${toy.toyName},unit price:${toy.unitPrice}' toy.method() println toy
Groovy类分析:
类、方法默认是public修饰符(Jad可以看到)
默认情况下Groovy编译的类属性是私有的
变量与方法使用动态类型
Groovy 自动提供构造函数,构造函数接受一个名称-值对的映射,名称-值对与类的属性相对应。可以不用初始化对象的每个属性。
生成标准的setter和getter方法
可以通过点号语法间接地访问属性
在进行属性操作时总是会调用setter和getter方法,即使直接通过点号语法访问属性也是如此
Groovy使用java的继承机制,支持方法覆盖与重载即多态
Groovy动态类型的特征,实际上使抽象类与接口变的不是很必要了
抽象类提供应该由子类延迟实现的方法即抽象方法
abstract class AbstractClassDemo{
def abstract doSomething()
//抽象类也可以包含具体的方法
String toString(){println 'Abstract class'}
接口作为子类必须遵守的协议,要求子类必须实现所有的方法,使用Java相同的机制
3.1 Groovy中File类介绍
Groovy对java.io.File进行了增强
def toys = new File("src/Testtoys.dat")
if(!toys.exists()){
toys.createNewFile()
toys.append("Groovy")
}
File类的其他常用方法:
Boolean delete():删除文件或目录
void eachFile(Closure cl):目录中每个文件应用闭包
void eachFileResurse(Closure cl):同上并对子目录递归
void eachLine(Closure cl):逐行遍历文件并应用闭包
String getPath():将抽象路径名转换成路径名字符串
String getText():读文件返回字符串
Boolean isDirectory():是否目录
Boolean mkdir():创建目录
----------------------------------------
4 Groovy操作数据库
GSql结合利用闭包和迭代器,把资源管理的负担转移到Groovy框架本身,从而简化JDBC编程
不用关闭Connection,也不用关闭ResultSet.
Groovy把迭代器变成隐含的,使用起来更简单
def coll = ["groovy","grails","java"]
coll.each{item->println item}
建立数据库连接
import groovy.sql.* def db = "jdbc:mysql://主机/数据库"?useUnicode=true&characterEncoding=UTF-8" def user ="root" //登陆名字 def password="lxt008" //用户密码 def driver="com.mysql.jdbc.Driver" //驱动 def sql = Sql.newInstance(db,user,password,driver) //需要把mysql的驱动jar包拷贝到项目lib目录下
数据库CRUD
sql.execute("sql语句") sql.eachRow("select * from toys"){toy-> println '\t\t'+toy.toyName+'\t'+toy.unitPrice } def searchToyName="toy1" sql.eachRow("select * from toys where toyName=?", [searchToyName]) { toy-> println "\t\t"+toy.toyName } def updateToyName="toy1" def updateUnitPrice ="100" sql.execute( "update toys set unitPrice=? where toyName=?", [updateUnitPrice,updateToyName])
操作DataSet类
DataSet类是Sql类的子类(可以用Jad查看)
def toys=sql.dataSet("表名")//反回一个DataSet toys.add(toyName:'toy8',unitPrice:'800') toys.each{toy-> println toy.toyName+":"+toy.unitPrice} def list = toys.rows() list.each{println it} def t = toys.firstRow() println t;
简单OR Mapping
SqlQuery抽象类(使用模板方法模式)
abstract class SqlQuery{ def sql; def query def SqlQuery(sql,query){ this.sql = sql; this.query = query} def abstract mapRow(row) def execute(){ def rowsList=sql.rows(query) def result=[] def size=rowsList.size() 0.upto(size-1){index-> results<<this.mapRow(rowsList[index]) } return results }
5. Groovy之swing:
构造器介绍:
可以生成xml/html/swing等嵌套树状数据结构
在语法级别上实现GOF的Builder设计模式
NodeBuilder:创建嵌套的节点树
DomBuilder:创建W3C DOM树
SwingBuilder:创建Swing界面
AntBuilder:生成ANT脚本
MarkupBuilder:创建XML或HTML标记
MarkupBuilder Demo: import groovy.xml.* def page=new MarkupBuilder() page.html{ head{title 'Hello'} body{ ul{ for(count in 1..3){ li 'st $count'} } } } SwingBuilder构造GUI import groovy.swing.SwingBuilder def sb = new SwingBuilder() //使用伪方法产生界面 def frame=sb.frame(title:'Store',location:[100,100],size:[300,300],defaultCloseOperation:WindowConstants.EXIT_ON_CLOSE){ label(text:"Hello world") } frame.pack() frame.setVisible(true) //Swing的伪方法改为大写,再在前面加上J,就是相应组件了 更好的组织代码: def sb = new SwingBuilder() def mainPanel={ sb.panel(layout:new GridLayout(2,2,5,5)){ label(text:'last name:',horizontalAlignment:JLabel.RIGHT) textField(text:"",columns:10) label(text:"first name:",horizontalAlignment:JLabel.RIGHT) textField(text:"",columns:10) } } def frame=sb.frame(title:"ToysStore",location:[100,100], size:[400,300],defaultCloseOperation:WindowConstants.EXIT_ON_CLOSE){ mainPanel() } frame.pack() frame.setVisible(true) BoxLayout: class FixedButton extends JButton{ Dimension getMinimumSize(){return BUTTONSIZE} Dimension getMaximumSize(){return BUTTONSIZE} Dimension getPreferredSize(){return BUTTONSIZE} private static final BUTTONSIZE= new Dimension(80,30)} def sb = new SwingBuilder() def mainPanel={ sb.panel(layout:new BorderLayout()){ hbox(constrains:BorderLayout.WEST){//hbox可以换成vbox def buttons=["one","two","three","four"] buttons.each{but-> sb.widget(new FixedButton(text:but)) } }}}} def frame=sb.frame(tiitl:"test",location:[100,100],size:[400,300],defaultCloseOperation:WindowConstants.EXIT_ON_CLOSE){ mainPanel() } frame.pack(), frame.setVisible(true);
JList/JScrollPane*********
class ListModel extends DefaultListModel{ ListModel(list){super() list.each{item->this.addElement(item)} } } def sb = new SwingBuilder() def listPanel={ sb.panel(constraints:BorderLayout.CENTER){ scrollPane(){ def list=["1","2","3"] toysList = list(model:new ListModel(list), selectionMode:ListSelectionModel.SINGLE_SELECTION, selectedIndex:0,visibleRowCount:4)}} def mainPanel={ sb.panel(layout:new BorderLayout()){ listPanel() }} } def frame=sb.frame(title:"Store",location:[100,100],size:[400,300],defaultCloseOperation:WindowConstants.EXIT_ON_CLOSE){ mainPanel() } frame.pack() frame.setVisible(true) JTable/JScrollPane************* def sb = new SwingBuilder() def tablePanel={ sb.panel(constraints:BorderLayout.CENTER){ scrollPane(){ table(selectionMode:ListSelectionModel.SINGLE_SELECTION){ def toyList =[[toyName:'toy1',unitPrice:'100'], [toyName:'toy2',unitPrice:'200']] tableModel(list:toyList){ closureColumn(header:'Toy Name',read:{row->return row.toyName}) closureColumn(header:"Unit Price",read:{row->return row.unitPrice}) } } } } def mainPanel={ sb.panel(layout:new BorderLayout()){ tablePanel() }} def frame = sb.frame(title:'Toys List',location:[100,100], size:[200,100],defaultCloseOperation: WindowConstants.EXIT_ON_CLOSE){ mainPanel()} frame.pack() frame.setVisible(true)
6.Groovy模板引擎**********************
Java语言具有Velocity和FreeMarker等
模板引擎与XSLT很类似
可以创建一个模板,包含一些占位符,在运行时替换为实际的值。模板引擎然后可能通过读取该模板并在这些占位符和运行时的值之间建立映射来实现对模板的转换。