Groovy是一种基于Java平台的面向对象语言。
在Groovy中,如在任何其他面向对象语言中一样,存在类和对象的概念以表示编程语言的对象定向性质。
Java和Groovy的语法非常相似。
Groovy 可以与 Java 语言无缝对接,在写 Groovy 的时候如果忘记了语法可以直接按Java的语法继续写,也可以在 Java 中调用 Groovy 脚本,都可以很好的工作,这有效的降低了 Java 开发者学习 Groovy 的成本。
Groovy的特点:
Groovy中的变量可以通过两种方式定义:
(1)使用数据类型,基本的数据类型有int、float、String等,基本与java相同;
(2)使用def关键字;
Groovy 句末不强制加分号。
与nodeJS比较
Groovy | nodeJS |
---|---|
int num=0;String str = “zhongfu”; 或 def num =0; def str = “zhongfu” ; | let num =0; let str = ‘zhongfu’; 或 var num = 0; var str = ‘zhongfu’ ; |
Groovy | nodeJs |
---|---|
println(“zhongfu”+”xinxi”); println “zhongfuxinxi”; print | console.log(“zhongfu”+”xinxi”); |
Groovy算数运算符、关系运算符、逻辑运算符、位运算符均与nodeJS一致。
Groovy 中==
等价于 Java 中的equals
方法。
//In Groovy
String str1 = "123";
String str2 = new String("123");
if(str1 == str2){
println("相等");
}else{
println("否");
}
// 打印 “相等”
Groovy支持范围运算符概念。
//这里定义了一个简单的整数范围,存储到一个局部变量称为范围内的下限为0和上限为5
def range = 0..5 ;
使用示例:
class Example {
static void main(String[] args) {
def range = 5..10;
println(range);
//get为从范围中获取对象,这里打印7
println(range.get(2));
}
}
Groovy循环语句支持while、for、for-in、break、continue,整体与nodeJS、java一致。
示例:
class Example {
static void main(String[] args) {
//for-in
int[] array = [0,1,2,3];
for(int i in array) {
println(i);
if(i == 2)
break;
}
//for-each
for(int i : array){
println i;
}
//结合范围运算符
for(i in 0..5){
println i //0,1,2,3,4,5
}
//for
for(int i = 0;i<5;i++) {
println(i);
}
//while
int count = 0;
while(count<5) {
println(count);
count++;
}
}
}
Groovy条件语句if/else、switch与Java、nodeJS 一致
**Groovy中的方法是使用返回类型或使用def关键字定义的。**方法的返回类型可以不需要声明,但需添加def
关键字。
定义参数时,不必显式定义类型。可以添加修饰符,如public,private和protected。默认情况下,如果未提供可见性修饰符,则该方法为public。
有返回值的方法return
可以被省略,默认返回最后一行代码的运行结果,如果使用了return
关键字则返回指定的返回值。
有形参的方法,调用时括号可以省略。
Groovy 方法的其他特性与Java一样,比如支持重载、不定长参数(…)等。
与nodeJS对照示例:
Groovy:
public class Example {
def DisplayName() {
println("This is how methods work in groovy");
println("This is an example of a simple method");
}
int sum(int a,int b){
int sum = a+b;
return sum;
}
//形参不必显示定义类型
def sum(a,b,c){
def sum = a+b+c;
//return 可以省略
sum;
}
def add(int a, int b) {
return a + b
}
public static void main(String[] args) {
Example ex = new Example();
ex.DisplayName();
println(ex.sum(1,2)); //3
println(ex.sum(1,2,3)); //6
println ex.sum('1','2','3'); //123
//有形参的方法括号可以省略
def sum = ex.add 1,2;
println sum; //3
}
}
NodeJS:
function sum1(a,b){
let sum = a+b;
return sum;
}
function sum2(a,b,c){
let sum = a+b+c;
return sum;
}
console.log(sum1(1,2));
console.log(sum2(1,2,3));
Groovy中可用的列表方法:
Groovy | NodeJS | 方法描述 |
---|---|---|
add( ) | push() | 将新值附加到此列表的末尾。 |
get( ) | 下标:list[] | 返回此列表中指定位置的元素。 |
contains( ) | indexOf() | 如果此列表包含指定的值,则返回true。 |
isEmpty( ) | 通过length() | 判空 |
minus( ) | 没有对应的方法 | 创建一个由原列表组成的除去指定元素的新列表 |
plus ( ) | 没有对应的原生方法 | 创建一个由原列表元素和指定的元素组成的新列表。 |
pop( ) | pop( ) | 从此列表中删除最后一个项目 |
remove( ) | splice(param,param) | 删除列表中指定位置的元素 |
reverse() | reverse() | 创建与原始列表的元素相反的新列表 |
size( ) | length() | 获取此列表中的元素数。 |
sort( ) | sort() | 返回原始列表的排序副本。 |
示例:
Groovy:
class Example {
static void main(String[] args) {
def lst = []; //定义一个空list
lst = [11, 12, 13, 14];
lst.add(15); //add
lst.pop(); //pop
println(lst.contains(12)); // true
//创建一个新的list,由原列表删除指定元素组成
def newlst = [];
newlst = lst.minus([12,13]);
println(newlst); // [11, 14]
//创建一个新的list,由原列表增加新元素构成
newlst = lst.plus([15,16]);
println(newlst); //[11, 12, 13, 14, 15, 16]
//删除List中的指定位置的元素,返回值为该元素的值
println(lst.remove(2)); // 13
println(lst); //[11, 12, 14]
//反转
def revlst = lst.reverse();
println(revlst); //[14, 12, 11]
//排序
def mst = [13, 12, 15, 14];
def newmst = mst.sort();
println(newmst); //[12, 13, 14, 15]
//遍历list,使用闭包
mst.forEach{
entry ->
println entry;
};
//13,12,15,14
mst.forEach{
println it; //it为Groovy的关键字
}
//13,12,15,14
}
}
NodeJS:
let list = [1,2,3,4,5,8];
list.push(7);
console.log(list);
console.log(list[0]);
console.log(list.indexOf(9)); // -1
list.splice(0,1);
list.sort();
console.log(list)
Groovy 定义数组的语法和 List 非常类似,区别在于数组的定义必须指定类型为数组类型,可以直接定义类型或者使用def定义然后通过as关键字来指定其类型。
String[] arrStr = ['Ananas', 'Banana', 'Kiwi'] //直接声明类型为数组类型 String[]
def numArr = [1, 2, 3] as int[] //通过as关键字指定类型为数组类型 int[]
assert numArr instanceof int[]
assert numArr.size() == 3
Groovy 定义 Map 的方式非常简洁,通过中括号包含key、val的形式,key和value以冒号分隔([key:value]
)。Groovy中的Map其实就是java.util.Map
,实现类默认使用的是java.util.LinkedHashMap
。
Groovy可用的映射方法:
方法 | 描述 |
---|---|
containsKey( ) | 是否包含此键 |
get( ) | 查找此Map中的键并返回相应的值。如果此映射中没有键的条目,则返回null。 |
keySet( ) | 获取此映射中的一组键。 |
put( ) | 将指定的值与此映射中的指定键相关联。如果此映射先前包含此键的映射,则旧值将替换为指定的值。 |
values | 返回此地图中包含的值的集合视图。 |
示例:
class Example {
static void main(String[] args) {
def map = [:] //定义一个空map
map = ['s' : 1, 'd' : 2]
map.put("shandong","jinan");
//修改value
map['s'] = 3;
print(map.get('s')); // 3
print(map.get('a')); // null
println(map.containsKey("s")); //true
println(map.containsKey("a")); //false
//返回一个Set包含map中所有的key
println(map.keySet()); //[s, d, shandong]
//返回一个Set包含map中所有的value
println(map.values()); //[1, 2, jinan]
//遍历 使用each 闭包
// each()接受两种形式的闭包:
//传递一个参数,那么这个参数代表map的一个entry;传递两个参数,那么就是key和value
def newMap = ['a':1,'b':2,'c':3];
newMap.each{
entry->
println entry.key + ":" +entry.value ;
}
// print a:1 b:2 c:3
newMap.each{
key,value ->
println key +":" +value;
}
//print a:1 b:2 c:3
}
}
Groovy操作SON
功能 | 库 |
---|---|
JsonBuilder | 构建建Json对象 |
JsonSlurper | JsonSlurper是一个将JSON字符串解析为Groovy数据的类结构,例如Map,List和原始类型,如整数,双精度,布尔和字符串。 |
JsonOutput | 此方法负责将Groovy对象序列化为JSON字符串 |
JsonBuilder:
构建Json示例:
import groovy.json.JsonBuilder
class GroovyTest {
static void main(String[] args) {
def json = new JsonBuilder();
json."state"{
"capital" "Denver"
"majorCities" "Denver", "Colorado Springs", "Fort Collins"
}
println json
//输出
// {"state":{"capital":"Denver","majorCities":["Denver","Colorado Springs","Fort Collins"]}}
def newJson = new JsonBuilder();
newJson {
"index" "line_peak"
"body" {
"size" 10000
"query" {}
}
}
println newJson;
//输出:
// {"index":"line_peak","body":{"size":10000,"query":{}}}
}
}
JsonSlurper:
JsonSlurper是一个将JSON文本内容解析为Groovy数据结构的类,如Map,List和原始类型,如Integer,Double,Boolean和String。
用JsonSlurper的时候需要注意,数组会被转换为ArrayList对象,而object会被转换为Map对象。在进行复杂对象处理的时候要留意这些返回值。
import groovy.json.JsonSlurper;
class GroovyTest {
static void main(String[] args) {
def jsonSlurper = new JsonSlurper();
//将Json字符串解析为Map
def object = jsonSlurper.parseText('{ "name": "John", "ID" : "1"}')
assert object instanceof Map;
println(object.name);
println(object.ID);
//解析时把能确定数据类型的解析为对应的数据类型
def obj = jsonSlurper.parseText('{"Integer": 12, "double": 12.55, "String": "groovy"}');
println(obj.Integer);
assert obj."Integer" instanceof Integer //true
println(obj.double);
assert obj."double" instanceof Double; //false
println(obj.String);
assert obj."String" instanceof String; //true
}
}
//json字符串转对象
import groovy.json.JsonSlurper;
import groovy.json.JsonBuilder
import groovy.json.JsonOutput
class Student{
String name;
int ID;
}
public class GroovyTest {
static void main(String[] args) {
def jsonSlurper = new JsonSlurper();
Student stu = jsonSlurper.parseText('{ "name": "John", "ID" : "1"}')
println stu.getName();
}
}
JsonOutput:
此方法负责将Groovy对象序列化为JSON字符串。
// 参数 -参数可以是数据类型的对象 - 数字,布尔,字符,字符串,日期,map,闭包等。
// 返回类型 -返回类型是一个JSON字符串。
Static string JsonOutput.toJson(datatype obj)
示例:
import groovy.json.JsonOutput
class GroovyTest {
static void main(String[] args) {
//Map转Json
def output = JsonOutput.toJson([name: 'John', ID: 1]);
println(output); // {"name":"John","ID":1}
}
}
//处理Groovy对象
import groovy.json.JsonOutput
class Student{
String name;
int ID;
}
class GroovyTest {
static void main(String[] args) {
def output = JsonOutput.toJson([ new Student(name: 'John',ID:1),
new Student(name: 'Mark',ID:2)]);
println output;
println "------------";
println JsonOutput.prettyPrint(output); //以树型输出Json字符串方便查看
}
}
//输出
[{"name":"John","ID":1},{"name":"Mark","ID":2}]
------------
[
{
"name": "John",
"ID": 1
},
{
"name": "Mark",
"ID": 2
}
]
类Date表示特定的时刻,具有毫秒精度。与java一致
//分配一个Date对象并初始化它,以便它表示分配的时间,以最近的毫秒为单位。
public Date()
//分配一个Date对象并将其初始化以表示自标准基准时间(称为“该历元”,即1970年1月1日,00:00:00 GMT)起指定的毫秒数。
public Date(long millisec)
示例:
Groovy:
和java一样,转换时间格式也是使用dateformat
class Example {
static void main(String[] args) {
Date date = new Date();
println(date.toString());
SimpleDateFormat myformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
println(myformat.format(date)); //2019-01-17 15:03:04
Date date1 = new Date(1000);
println(myformat.format(date)); //1970-01-01 08:00:01
}
}
NodeJS:
//使用moment
moment().format("YYYY-MM-DD");
处理时间的相关方法:
方法 | 描述 |
---|---|
after() | 测试此日期是否在指定日期之后。 |
equals() | 比较两个日期的相等性。当且仅当参数不为null时,结果为true,并且是表示与该对象时间相同的时间点(毫秒)的Date对象。 |
compare() | 比较两个日期的顺序。 |
toString() | 将此Date对象转换为字符串 |
before() | 测试此日期是否在指定日期之前。 |
getTime() | 返回自此Date对象表示的1970年1月1日,00:00:00 GMT以来的毫秒数。 |
setTime() | 设置此Date对象以表示一个时间点,即1970年1月1日00:00:00 GMT之后的时间毫秒。 |
捕捉异常:
与 Java和 NodeJs相同,使用try、catch捕捉异常
try{
.....
}catch(Exception1 ex){
.....
}catch(Exception2 ex){
......
}finally{
......
}
以下是Groovy中提供的异常方法 :
public String getMessage()
返回有关已发生异常的详细消息。此消息在Throwable构造函数中初始化。
public Throwable getCause()
返回由Throwable对象表示的异常原因。
public String toString()
返回与getMessage()的结果连接的类的名称。
public void printStackTrace()
将toString()的结果与堆栈跟踪一起打印到System.err,错误输出流。
public StackTraceElement [] getStackTrace()
返回包含堆栈跟踪上的每个元素的数组。索引0处的元素表示调用堆栈的顶部,数组中的最后一个元素表示调用堆栈底部的方法。
public Throwable fillInStackTrace()
使用当前堆栈跟踪填充此Throwable对象的堆栈跟踪,添加到堆栈跟踪中的任何以前的信息。
在Groovy中,如在任何其他面向对象语言中一样,存在类和对象的概念以表示编程语言的对象定向性质。
Groovy 默认会隐式的创建getter、setter方法,并且会提供带参的构造器。
下面两者是等价的。
// In Java
public class Person {
private String name;
Person(String name) {
this.name = name
}
public String getName() {
return name
}
public void setName(String name) {
this.name = name
}
}
// In Groovy
class Person {
String name;
int ID;
}
class Test {
static void main(String) {
def person = new Person(name: '张三')
println person.getName(); // 张三
person.setID(2014);
println person.getID(); /2014
}
}
Groovy同样支持继承、内部类、抽象类、接口,和Java一致。
Groovy 提供了闭包的支持。简单来说就是一段可执行的代码块或函数指针。闭包在 Groovy 中是groovy.lang.Closure
类的实例,这使得闭包可以赋值给变量,或者作为参数传递。
闭包的语法:
//闭包的参数为可选项
def closure = { [closureParameters -> ] statements }
闭包调用的方式有两种,闭包.call(参数)或者闭包(参数),在调用的时候可以省略圆括号。
//带参闭包
def closure = {
param -> println param
}
closure('hello') //hello
closure.call('hello')
closure 'hello'
//如果只有一个参数的话,也可省略参数的定义,Groovy提供了一个隐式的参数it来替代它。
def closure1 = { it -> println it }
//和上面是等价的
def closure2 = { println it }
closure2('hello')
//多个参数以逗号分隔,参数类型可省略
def closur3 = { String x, int y ->
println "key ${x} the value is ${y}"
}
closure3('a',1); // key a the value is 1
//闭包的参数是可选的,如果没有参数的话可以省略->操作符。
def closure4 = {println 'hello'}
closure4()
//闭包可以访问外部变量
def str = 'hello'
def closur5={
println str
}
closur5()//hello
闭包可以作为方法的参数传入,闭包作为方法的唯一参数或最后一个参数时可省略括号.
def eachLine(lines, closure) {
for (String line : lines) {
closure(line)
}
}
eachLine('a'..'z',{ println it })
//可省略括号,与上面等价
eachLine('a'..'z') { println it }
List和Map使用闭包:
List遍历:
在下面的例子中,我们首先定义一个简单的值列表。列表集合类型然后定义一个名为.each的函数。此函数将闭包作为参数,并将闭包应用于列表的每个元素。
def lst = [11, 12, 13, 14];
lst.each {println it}
lst.forEach{
println it;
}
lst.each{
num ->
if(num % 2 == 0)
println num+"可以被2整除";
}
Map遍历:
在下面的例子中,我们首先定义一个简单的关键值项Map。然后,映射集合类型定义一个名为.each的函数。此函数将闭包作为参数,并将闭包应用于映射的每个键值对
def map = ["a" : 1, "b" : 2]
map.each {println it}
map.each {
entry ->
println entry.key + ":" +entry.value;
}
map.each{
key,value->
println key +":"+value;
}
map.forEach{
key,value -> println key+":"+value;
}
闭包本身提供的一些方法。
方法 | 描述 | 返回值 |
---|---|---|
find() | 方法查找集合中与某个条件匹配的第一个值。 | object |
findAll() | 它找到接收对象中与闭合条件匹配的所有值。 | List |
any() & every() | 方法any迭代集合的每个元素,检查布尔谓词是否对至少一个元素有效。 | boolean |
collect() | 该方法通过集合收集迭代,使用闭包作为变换器将每个元素转换为新值。 | List |
示例:
class GroovyTest {
static void main(String[] args) {
def lst = [1,2,3,4];
def value = lst.find {element -> element > 2}
println(value); // 打印第一个符合条件的 3
def value1 = lst.findAll{element -> element > 2}
value1.each {println it} //打印所有符合条件的元素 3,4
//是否所有元素均大于2
value2 = lst.every{element -> element > 2}
println(value2); //false
// 是否有元素大于2
def value3 = lst.any{element -> element > 2}
println(value3); //true
//collect
def newlst = lst.collect {element -> return element * element}
println(newlst); //[1,4,9,16]
}
}