Groovy学习笔记
Groovy控制台
- Groovy编译:groovyc filename.groovy
- Groovy运行:groovy filename
- Groovy控制台:groovyConsole
默认导入
- groovy.lang.*
- groovy.util.*
- java.lang.*
- java.io.*
- java.math.BigDecimal.*
- java.math.BigInteger.*
- java.net.*
- java.util.*
动态类型
1 2 3 4 5 | x = new Date(); x = 1; //动态类型
double y = -3.1415926; y = new Date(); //静态类型,出现错误
|
列表与映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | jvmLanguages = ["java","Groovy","Scala","Clojure"]; println(jvmLanguages[0]); println(jvmLanguages.size()); println(jvmLanguages[0..2]); println(jvmLanguages[-1]); jvmLanguages = []; println(jvmLanguages);
languagesRatings = [Java:100, Groovy:99, Clojure:"N/A"]; println(languagesRatings["java"]); println(languagesRatings.Clojure); languagesRatings["Clojure"] = 75; languagesRatings = [:]; println languagesRatings;
|
可选的语法
- 可选的分号和返回语句
1 2 3 4 5 6 7 | public class Test{ public Integer doStuff(){ def x = 1 //没有分号 def y; def String z = "Hello"; x = 3 //默认返回 } }
|
- 可选的参数括号
1 2 | println("It's Groovy baby, year!") //等同于 println "It's Groovy baby, year!"
|
访问限定符与比较操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Test{ //默认为public
Integer x = new Integer(2) Integer y = new Integer(2) Integer z = null
Integer doStuff(){ //默认为public if (x == y){ //隐含equals()调用 println "x==y" } if (!x.is(y)){ //检查对象是否相等 println "x is not y" } if (z.is(null)){ //检查是否为null println "z is null" } if (z == null){ //检查是否为null println "z is null" } } }
|
GroovyBean
1 2 3 4 5 6 | class Character{ private int strength private int wisdom } def pc = new Character(strength:10, wisdom:15) //bean初始化 pc.strength = 15 //set方法
|
安全解引用操作符
1 2 3 4 | people = [null, new Person(name:"liyongjie")] for (Person person : people){ println people?.name }
|
猫王操作符
1 2 3 4 5 6 7 | // Java String agentStatus = "Active"; String status = agentStatus != null ? agentStatus : "Inactive"; // Groovy String status = agentStatus ? agentStatus : "Inactive" // or String status = agentStatus ? "Inactive"
|
增强型字符串GString和跨行字符串
1 2 3 4 5 6 7 | //GString,不能用于映射中的键或者比较是否相等 String name = "liyongjie" def dist = 3 * 2 String crawling = "${name} is crawling ${dist} feet!" //跨行字符串 """This GString wraps over two lines"""
|
函数字面值
1 2 3 4 5 6 7 8 | def sayHello = { name -> if (name == "Martijn" || name == "Ben") "Hello author" + name + "!" else "Hello reader" + name + "!" } println(sayHello("Martijn"))
|
内置的集合操作
方法 | 描述 |
each | 遍历集合,对其中的每一项应用函数字面值 |
collect | 收集在集合中每一项上应用函数字面值的返回结果(相当于其他语言map/reduce中的map函数) |
inject | 用函数字面值处理集合并构建返回值(相当于其他语言里map/reduce中的reduce函数) |
findAll | 找到集合中所有与函数字面值匹配的元素 |
max | 返回集合中的最大值 |
min | 返回集合中的最小值 |
1 2 3 4 | movieTitles = ["seven","show","hard"] movieTitles.each({x -> println x}) // 使用隐含的it变量 movieTitles.each({println it})
|
对正则表达式的内置支持
方法 | 描述及Java中的对等物 |
~ | 创建一个模式(创建一个编译的Java Pattern对象) |
=~ | 创建一个匹配器(创建一个Java Matcher对象) |
==~ | 计算字符串(相当于在Pattern上调用match()方法) |
1 2 3 4 5 6 7 | Pattern pattern = Pattern.compile("1010"); String input = "1010"; Matcher matcher = pattern.matcher(input); if (input.matches("1010")){ input = matcher.replaceFirst("0101"); System.out.println(input); }
|
1 2 3 4 5 6 7 8 9 10 | def pattern = /1010/ def input = "1010" def matcher = input =~ pattern if (input ==~ pattern){ input = matcher.replaceFirst("0101") println input }
( "Hazel 1" =~ /(\w+)(\d+)/ ).each {full, name, age -> println "${name} is ${age} years old."}
|
简单的XML处理
构造XML
1 2 3 4 5 6 7 | def writer = new StringWriter() def xml = new groovy.xml.MarkupBuilder(writer) xml.person(id:2) { name "Gweneth" age 1 } println.writer.toString() |
输出的XML为:
1 2 3 4 | <person id='2'> <name>Gweneth</name> <age>1</age> </person>
|
集中解析XML的方法
方法 | 描述 |
XMLParser | 支持XML文档的GPath表达式 |
XMLSlurper | 跟XMLParser类似,但以懒加载的方式工作 |
DOMCategory | 用一些语法支持DOM的底层解析 |
解析XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class XmlExample { static def PERSON = """ <person id='2'> <name>Gweneth</name> <age>1</age> </person> """ } class Person {def id; def name; def age}
def xmlPerson = new XMLParser(). parseText(XmlExample.PERSON) Person p = new Person(id:xmlPerson.@id, name:xmlPerson.name.text(), age:xmlPerson.age.text()) println "${p.id}, ${p.name}, ${p.age}"
|
Groovy与Java的合作
tip:只需要把GROOVY_HOME/embeddable/Groovy-all-xxx.jar文件放到CLASSPATH中
下面是几种从Java调用Groovy代码的方法
- 使用Bean Scripting Framework(BSF),即JSR 233
- 使用GroovyShell
- 使用GroovyClassLoader
- 使用GroovyScriptEngine
- 使用嵌入式Groovy控制台
GroovyShell
1 2 3 4 5 6 | Binding binding = new Binding(); binding.setVariable("x", 2.4); binding.setVariable("y", 8); GroovyShell shell = new GroovyShell(binding); //设置shell上的binding Object value = shell.evaluate("x + y"); //计算并返回表达式 assert value.equals(new BigDecimal(10.4)); |
GroovyClassLoader
1 2 3 4 5 6 7 8 9 10 11 12 | GroovyClassLoader loader = new GroovyClassLoader(); //准备类加载器 Class<?> groovyClass = loader.parseClass( new File("CalculateMax.groovy")); //从类文件得到Class对象 GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); //生成实例对象 ArrayList<Integer> numbers = new ArrayList(); numbers.add(new Integer(1)); //准备参数 numbers.add(new Integer(10)); Object[] arguments = {numbers}; Object value = GroovyObject .invokeMethod("getMax", arguments); //调用groovy方法 assert value.equals(new Integer(10)) |
GroovyScriptEngine
1 2 3 4 5 6 7 8 | String[] roots = new String[] {"/src/main/groovy"}; //设置根目录 GroovyScriptEngine gse = new GroovyScriptEngine(roots); //初始化引擎 Binding binding = new Binding(); binding.setVariable("name","liyongjie");
Object output = gse.run("Hello.groovy", binding); //运行脚本 assert output.equals("Hello liyongjie"); |