环境安装:
JDK环境,如果用AndroidStudio的话可以跳过该步骤,因为AndroidStudio的JDK 及 Groovy已默认配置好
官网下载:http://www.groovy-lang.org/download.html
可以直接下载压缩包,解压,手动配置环境变量
或(推荐)直接下载Windows Installer并安装,环境变量自动配好。
打开cmd -> groovy -version 验证
或者用在线运行环境 :
https://tool.lu/coderunner/
http://www.dooccn.com/groovy/
Groovy HelloWorld:
1.命令行
创建helloworld.groovy文件:
class Fuck{
static void main(String[] args){
println "Hello World3";
}
}
Shift 鼠标右键-> 在此处打开命令窗口
运行命令 groovy helloworld.groovy
2.Groovy安装后在%GROOVY_HOME%/bin下找到groovyConsole.exe或groovyConsole.bat.
image.pngCtrl Enter / Ctrl R 运行。
同时支持选中部分运行
3使用AndroidStudio:
Ctrl+Shift+A->选择Groovy Console即可
image.png
或双击Shift->选择Groovy Console
image.png
出现两个窗口:Groovy脚本输入窗口,和Run脚本输出窗口
Ctrl Enter / Ctrl R 运行。
同时支持选中部分运行
对比Java
-
Default imports
java.io.*
java.lang.*
java.math.BigDecimal
java.math.BigInteger
java.net.*
java.util.*
groovy.lang.*
groovy.util.* -
Multi-methods 或者叫Runtime Dispatch
java基于方法声明的类型,在编译期间就确定了调用的方法,而Groovy则是在运行时来判断参数的类型,而动态的调用相应的方法。
int method(String arg) {
return 1;
}
int method(Object arg) {
return 2;
}
Object o = "Object";
int result = method(o);
Java运行后 result为2;
而Groovy运行后 result 为1;
-
Array initializers
Groovy 中的{...}被保留用作闭包,数组初始化使用[]。
Java: int[] array = {1, 2, 3}
Groovy: int[] array = [1, 2, 3] -
Package scope visibility
class Person {
String name
}
Java中,成员变量不定义访问控制符的情况下为default, 包相同的类中可以访问。即package-private
Groovy中,不定义访问控制符的成员变量被用于创建一个属性,即一个私有成员变量,一个关联的getter和一个关联的setter。如果希望达到Java包私有的效果,只需要加注释@PackageScope
class Person {
@PackageScope String name
}
- 不支持ARM blocks (Automatic Resource Management)
Path file = Paths.get("/path/to/file");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
可以写成:
new File('/path/to/file').eachLine('UTF-8') {
println it
}
或更接近于Java写法的:
new File('/path/to/file').withReader('UTF-8') { reader ->
reader.eachLine {
println it
}
}
- Lambdas
Java8支持的Lambdas
Runnable run = () -> System.out.println("Run");
list.forEach(System.out::println);
Groovy不支持,但是通过闭包实现相同效果。
Runnable run = { println 'run' }
list.each { println it } // or list.each(this.&println)
Extra keywords
Groovy比Java多出以下几个关键字:as, def, in, trait
Grammar
Groovy是基于JVM的开发语言,与Java有很多相似之处。以下只介绍与Java不同的语法:
范围运算符
class Example {
static void main(String[] args) {
//1..10 - 包含范围的示例
//1 .. <10 - 独占范围的示例
//'a'..'x' - 范围也可以由字符组成
//10..1 - 范围也可以按降序排列
//'x'..'a' - 范围也可以由字符组成并按降序排列。
def range = 5..10;
println(range);
println(range.get(2));
}
}
[5, 6, 7, 8, 9, 10]
7
方法
//返回类型用具体的或使用def关键字定义, 方法可以接收任意数量的参数
//定义参数时,不必显式定义类型
//修饰符public,private和protected。不写默认为public
def methodName() {
//Method code
}
static def DisplayName(parameter1, parameter2 = 0, parameter3 = 0) {
//参数设置默认值,调用DisplayName(1)时,会默认使用 parameter2,parameter3的默认值。
}
static void main(String[] args) {
}
文件操作
import java.io.File
class Example {
static void main(String[] args) {
//读取文件
new File("E:/Example.txt").eachLine {
line -> println "line : $line";
}
//读取文件的内容
File file = new File("E:/Example.txt")
println file.text
//写入文件
new File('E:/','Example.txt').withWriter('utf-8') {
writer -> writer.writeLine 'Hello World'
}
//获取文件的大小
File file = new File("E:/Example.txt")
println "The file ${file.absolutePath} has ${file.length()} bytes"
//测试文件是否是目录
def file = new File('E:/')
println "File? ${file.isFile()}"
println "Directory? ${file.isDirectory()}"
//创建目录 删除文件
def file = new File('E:/Directory')
file.mkdir()
file.delete()
//复制文件
def src = new File("E:/Example.txt")
def dst = new File("E:/Example1.txt")
dst << src.text
//显示机器上的驱动器
def rootFiles = new File("test").listRoots()
rootFiles.each {
file -> println file.absolutePath
}
//列出特定目录中的文件
new File("E:/Temp").eachFile() {
file->println file.getAbsolutePath()
}
//显示目录及其子目录中的所有文件
new File("E:/temp").eachFileRecurse() {
file -> println file.getAbsolutePath()
}
}
}
数字
rint(): 返回值最接近参数的整数
class Example {
static void main(String[] args){
double d = 100.675;
double e = 100.500;
double f = 100.200;
System.out.println(Math.rint(d));
System.out.println(Math.rint(e));
System.out.println(Math.rint(f));
}
}
101.0
100.0
100.0
toRadians():参数值转换为弧度
class Example {
static void main(String[] args) {
double x = 45.0;
double y = 30.0;
System.out.println( Math.toRadians(x) );
System.out.println( Math.toRadians(y) );
}
}
0.7853981633974483
0.5235987755982988
字符串
class Example {
static void main(String[] args) {
String a = 'Hello Single';
String b = "Hello Double";
String c = "'Hello Triple" + "Multiple lines'";
println(a);
println(b);
println(c);
//字符串索引
println(sample[4]); // Print the 5 character in the string
println(sample[-1]); //Print the 1st character in the string starting from the back
println(sample[1..2]);//Prints a string starting from Index 1 to 2
println(sample[4..2]);//Prints a string starting from Index 4 back to 2
//字符串重复
String a = "Hello";
println("Hello"*3);
println(a*3);
}
}
Hello Single
Hello Double
'Hello TripleMultiple lines'
o
d
el
oll
HelloHelloHello
HelloHelloHello
列表
[11,12,13,14] - 整数值列表
['Angular','Groovy','Java'] - 字符串列表
[1,2,[3,4],5] - 嵌套列表
['Groovy',21,2.11] - 异构的对象引用列表
[] - 一个空列表
class Example {
static void main(String[] args) {
def lst = [11, 12, 13, 14];
println(lst);
lst.add(15);//将新值附加到此列表的末尾。
println(lst);
lst.add(2,20);//将新值附加到列表中的特定位置。
println(lst);
println(lst.contains(12)); //true
println(lst.contains(18));//false
println(lst.get(0));//11
println(lst.get(2));//13
println(lst.isEmpty()); //false
//从列表中减去的值的集合。
def newlst = [];
newlst = lst.minus([12,13]);
println(newlst); //[11, 14]
newlst = lst.plus([15,16]);
println(newlst); //[11, 14, 15, 16]
//从此列表中删除最后一个项目。
println(lst.pop()); //14
println(lst); //[11, 12, 13]
//删除此列表中指定位置的元素。
println(lst.remove(2));//13
println(lst);//[11, 12]
//创建与原始列表的元素相反的新列表
def revlst = lst.reverse();
println(revlst); //[12, 11]
//排序
def newlst = lst.sort();
println(newlst);//[11, 12]
println(lst.size);//2
}
}
[11, 12, 13, 14]
[11, 12, 13, 14, 15]
[11, 12, 20, 13, 14, 15]
正则
有两个特殊的位置字符用于表示一行的开始和结束:caret(∧)和美元符号($)。
正则表达式也可以包括量词。加号(+)表示一次或多次,应用于表达式的前一个元素。
星号(*)用于表示零个或多个出现。问号(?)表示零或一次。
元字符{和}用于匹配前一个字符的特定数量的实例。
在正则表达式中,句点符号(。)可以表示任何字符。这被描述为通配符。
正则表达式可以包括字符类。一组字符可以作为简单的字符序列,包含在元字符[和]中,如[aeiou]中。对于字母或数字范围,可以使用[a-z]或[a-mA-M]中的短划线分隔符。字符类的补码由方括号内的前导插入符号表示,如[∧a-z]中所示,并表示除指定的字符以外的所有字符。下面给出了正则表达式的一些示例。
以下都为true
'Groovy' =~ 'Groovy' //true
'Groovy' =~ 'oo' //true
'Groovy' ==~ 'Groovy' //true
'Groovy' ==~ 'oo' //false
'Groovy' =~ '∧G' //true
‘Groovy' =~ 'y$' //true
‘Groovy' =~ 'Gro*vy' //true
'Groovy' =~ 'Gro{2}vy'//true
特征
可以被看作是承载默认实现和状态的接口。使用trait关键字定义
class Example {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1;
st.Marks1 = 10;
println(st.DisplayMarks());
println(st.DisplayTotal());
}
}
interface Total {
void DisplayTotal()
}
trait Marks implements Total { //实现接口
void DisplayMarks() {
println("Display Marks");
}
void DisplayTotal() {
println("Display Total");
}
}
class Student implements Marks {
int StudentID
int Marks1;
}
Display Marks
Display Total
闭包
class Example {
static void main(String[] args) {
def clos = {println "Hello World"}; //{println "Hello World"}即为闭包
clos.call();//代码块可以使用call语句执行
}
}
class Example {
static void main(String[] args) {
def clos = {param->println "Hello ${param}"};//包含形式参数
clos.call("World");
}
}
class Example {
static void main(String[] args) {
def clos = {println "Hello ${it}"};//这里的'it'是Groovy中的关键字
clos.call("World"); //Hello World
}
}
class Example {
def static Display(clo) {
clo.call("Inner");
}
static void main(String[] args) {
def str1 = "Hello";
def clos = { param -> println "${str1} ${param}" }//闭包内引用变量
clos.call("World");//Hello World
str1 = "Welcome";
clos.call("World");// Welcome World
Example.Display(clos);// Welcome Inner
}
}
class Example {
static void main(String[] args) {
def lst = [11, 12, 13, 14];
lst.each {println it}//each接收一个Closure参数, 应用在数组的每一项.
lst.each{num -> if(num % 2 == 0) println num} // 12 14
}
}
class Example {
static void main(String[] args) {
def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"]
mp.each {println it}
//TopicName = Maps
//TopicDescription = Methods in Maps
mp.each {println "${it.key} maps to: ${it.value}"}
//TopicName maps to: Maps
//TopicDescription maps to: Methods in Maps
}
}
class Example {
static void main(String[] args) {
def lst = [1,2,3,4];
def value;
value = lst.find {element -> element > 2} // 查找集合中与某个条件匹配的第一个值
println(value);//3
value = lst.findAll{element -> element > 2}//找到接收对象中与闭合条件匹配的所有值。
value.each {println it}//3, 4
// Is there any value above 2
value = lst.any{element -> element > 2}
println(value);//true
// Is there any value above 4
value = lst.any{element -> element > 4}
println(value); //false
// Are all value above 2
value = lst.every{element -> element > 2}
println(value);//false
// Are all value above 4
value = lst.every{element -> element > 4}
println(value); //false
def largelst = [4,5,6];
// Are all value above 2
value = largelst.every{element -> element > 2}
println(value);//true
def lst = [1,2,3,4];
def newlst = [];
newlst = lst.collect {element -> return element * element}//通过集合收集迭代,使用闭包作为变换器将每个元素转换为新值。
println(newlst);//[1, 4, 9, 16]
}
}
XML
Groovy中的XML支持
Groovy语言还提供了对XML语言的丰富支持。使用的两个最基本的XML类是 -
XML标记构建器 - Groovy支持基于树的标记生成器BuilderSupport,它可以被子类化以生成各种树结构对象表示。通常,这些构建器用于表示XML标记,HTML标记。 Groovy的标记生成器捕获对伪方法的调用,并将它们转换为树结构的元素或节点。这些伪方法的参数被视为节点的属性。作为方法调用一部分的闭包被视为生成的树节点的嵌套子内容。
import groovy.xml.MarkupBuilder
class Example {
static void main(String[] args) {
def mB = new MarkupBuilder()
// Compose the builder
mB.collection(shelf : 'New Arrivals') {
movie(title : 'Enemy Behind')
type('War, Thriller')
format('DVD')
year('2003')
rating('PG')
stars(10)
description('Talk about a US-Japan war')
}
}
}
<collection shelf = 'New Arrivals'>
<movie title = 'Enemy Behind' />
<type>War, Thriller</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie>
</collection>
XML解析器 - Groovy XmlParser类使用一个简单的模型来将XML文档解析为Node实例的树。每个节点都有XML元素的名称,元素的属性和对任何子节点的引用。这个模型足够用于大多数简单的XML处理。
class Example {
static void main(String[] args) {
def parser = new XmlParser()
def doc = parser.parse("D:Movies.xml");
doc.movie.each{
bk->
print("Movie Name:")
println "${bk['@title']}"
print("Movie Type:")
println "${bk.type[0].text()}"
print("Movie Format:")
println "${bk.format[0].text()}"
print("Movie year:")
println "${bk.year[0].text()}"
print("Movie rating:")
println "${bk.rating[0].text()}"
print("Movie stars:")
println "${bk.stars[0].text()}"
print("Movie description:")
println "${bk.description[0].text()}"
println("*******************************")
}
}
}
监视JVM
import java.lang.management.*
def os = ManagementFactory.operatingSystemMXBean
println """OPERATING SYSTEM:
OS architecture = $os.arch
OS name = $os.name
OS version = $os.version
OS processors = $os.availableProcessors
"""
def rt = ManagementFactory.runtimeMXBean
println """RUNTIME:
Runtime name = $rt.name
Runtime spec name = $rt.specName
Runtime vendor = $rt.specVendor
Runtime spec version = $rt.specVersion
Runtime management spec version = $rt.managementSpecVersion
"""
def mem = ManagementFactory.memoryMXBean
def heapUsage = mem.heapMemoryUsage
def nonHeapUsage = mem.nonHeapMemoryUsage
println """MEMORY:
HEAP STORAGE:
Memory committed = $heapUsage.committed
Memory init = $heapUsage.init
Memory max = $heapUsage.max
Memory used = $heapUsage.used NON-HEAP STORAGE:
Non-heap memory committed = $nonHeapUsage.committed
Non-heap memory init = $nonHeapUsage.init
Non-heap memory max = $nonHeapUsage.max
Non-heap memory used = $nonHeapUsage.used
"""
println "GARBAGE COLLECTION:"
ManagementFactory.garbageCollectorMXBeans.each { gc ->
println " name = $gc.name"
println " collection count = $gc.collectionCount"
println " collection time = $gc.collectionTime"
String[] mpoolNames = gc.memoryPoolNames
mpoolNames.each {
mpoolName -> println " mpool name = $mpoolName"
}
}
结果:
OPERATING SYSTEM:
OS architecture = amd64
OS name = Windows 10
OS version = 10.0
OS processors = 8
RUNTIME:
Runtime name = 6164@DESKTOP-UBF4S8B
Runtime spec name = Java Virtual Machine Specification
Runtime vendor = Oracle Corporation
Runtime spec version = 1.8
Runtime management spec version = 1.2
MEMORY:
HEAP STORAGE:
Memory committed = 257425408
Memory init = 268435456
Memory max = 3790077952
Memory used = 46437528 NON-HEAP STORAGE:
Non-heap memory committed = 21168128
Non-heap memory init = 2555904
Non-heap memory max = -1
Non-heap memory used = 20688832
GARBAGE COLLECTION:
name = PS Scavenge
collection count = 1
collection time = 3
mpool name = PS Eden Space
mpool name = PS Survivor Space
name = PS MarkSweep
collection count = 0
collection time = 0
mpool name = PS Eden Space
mpool name = PS Survivor Space
mpool name = PS Old Gen
Result: [sun.management.GarbageCollectorImpl@2bfc268b, sun.management.GarbageCollectorImpl@2f8dad04]
网友评论