由浅入深的了解Groovy的基本使用
0、安装Groovy
1、解压并配置环境变量
GROOVY_HOME=F:\project\Groovy
2、输入groovy -v
查看版本信息
1、了解前提
1.1、什么是Groovy?
Groovy是机遇Java虚拟机的一种敏捷的动态语言,它是一种成熟的OOP(面向对象)编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言的其他特性。
1.2、于Java相比,Groovy的不同点或优势
1、Groovy完全兼容Java语法,可以做脚本也可以做类
2、分号是可选的,一般不会写,都是使用换行作为结束
3、类、方法、字段都是公开的,没有访问权限限制
4、默认生成具名(名值对)参数构造器 key: value
5、字段不定于访问权限时,编译器自动给字段添加 getter/setter方法
6、字段可以使用点来获取,无访问权限的也可使用getter/setter操作
7、方法可以省略return关键字,自动检索最后一行最为返回值。
8、空值比较不会出现空指针异常。
1.3、Groovy的高级特性
1、assert断言:可以用assert代替之前的Java的断言语句。
2、可选类型:可使用类JavaScript的弱类型,可使用def来表示任意类型。
3、方法调用:调用带参数的方法可以省略括号
4、字符串定义:字符串定义有三种方式,单引号,双引号和三引号
5、集合API:Groovy有自己的API也兼容Java的API
6、闭包:Groovy的一大特性,跟方法类似的代码块,他可以作为一个变量的值,也可以是一个参数传递给一个方法。
{// 这样就是一个闭包
}
2、学习路线
2.1、数据语法
2.1.1、list类型
/**
* 添加数据
*/
list = []
// 添加数据
list.push(123)
list << ("123we")
//如果想要强制添加某一个数据需要加上 as 来指定类型
list << (1 as Integer)
list << ("123" as String)/**
* 遍历数据
*/
for (int i = 0; i < 10; i++) {println(list[i])
}
for (iten in list) {println("你好")println(iten)
}
list.stream().forEach((item) -> {println(item)
})
list.each {println(it)
}
2.1.2、map
// 定义
def map = [a: 2, b: new Date()]
// 写入
map.put('aaa', 'bbbbb')// 写入
map.a = 23 as Integer//println(map)
//println(map.a)println("----------------------")
2.1.3、在Groovy中任何数据都是对象
// 循环100次
100.times { println(it) }
a = " 123 ".trim()
println(a)
a = true.compareTo(true)
println(a)
2.1.4、类的属性操作更简单
class JavaBean {String a;
}
def bean = new JavaBean()
def a = bean.a
println(a)
2.1.5、格式化输出字符串
aa = 10
bb = 1
xx = "我是aa,我的值:${aa};我是bb,我的值:$bb"
println(xx)
2.1.6、switch
def x = new JavaBean()switch (x) {case [1, 2, 3, 4]:println("当数据为1,2,3,4中一个数据时就可以走这里")breakcase 10..10000:println("这里的10..10000表示从10到10000的闭区间所有的整数")breakcase Date:println("这里表示x是一个时间")breakcase JavaBean:println("这里表示是一个JavaBean对象")breakdefault:println("都不走走这里")
}
2.1.7、闭包下的默认变量
/**闭包*//*** it:当闭包方法中,没有定义任何参数时,也可以直接用it遍历* */
println("----------it-----------")
list = [1, 2, 3, 4, 5, 6]
list.each { println(it) }/*** this+owner:基本跟this一样,处理一种情况:如果该闭包是在其他的闭包中定义的,那么owner就是只想定义它的闭包对象* */
println("----------this+owner-----------")
def xx = {println("xx的:" + this)println("xx的:" + owner)def aa = {println("aa的:" + this)println("aa的:" + owner)}aa.call()
}xx.call()/*** delegate* */
println("----------delegate-----------")
def myDelegate = {println(this)println(owner)println(delegate)
}myDelegate.call()
println("----------执行setDelegate-----------")
myDelegate.setDelegate("abc")
myDelegate.call()
2.1.8、元编程
在Groovy中,可以使用metaClass
类来对元数据添加属性和方法
如String类,添加一个uppers方法
aa = "wdwd"
String.metaClass.toUpper = {-> toUpperCase();
}
def upper = aa.toUpper()
println(upper)
String.metaClass.to = {-> toString()
}
def to = "2".to()
println(to)
2.1.9、强数据类型检查
@TypeChecked
class Type {// Integer a = 1.0 这里会报错:Cannot assign 'BigDecimal' to 'Integer'
}list = [1, 2, 3, 4]
list.push(2 as Integer) // 通过as检查2是不是Integer数据类型
2.1.10、三目运算
/*** 三目运算* */
a = true
san = a ?: "当a为空或者为false是走这里"
2.1.11、安全访问
/*** 安全访问* */
class Person {String age;
}Person person = new Person()
def age = person?.age
println(age)
2.2、Groovy自带工具
使用
groovyConsole groovy
可以启动groovy
的自带的idea.groovyc
:自带的变异工具,使用他可以拿到编译后的java
文件.使用
groovysh
可以打开shell可以编写groovy.groovydoc
:文件生成工具
2.3、GDK
2.3.1、自带的集合方法
1、排序
1.1、sort
sort:对集合进行排序,这个方法,可以接受一个闭包参数,或者无参。
/*** 排序* */list = [23, 41, 421, 23, 12, 3]def sortInc = list.sort() // 默认为升序排序
println("排序后:" + sortInc)// 自定义排序
println("----------自定义排序---------------")
def newList = list.sort({a, b -> a - b ? -1 : 1
})
println(newList)b = -10
c = 1
a = b - c ? -1 : 1 // 只有b和c的值都相等时做减法a的值才为1,其余都为-1
println(a)
1.2、reverse
reverse:将原list倒序,返回一个新的list
2、find
2.1、findAll
findAll:返回符合条件的元素,他可以接收一个闭包参数或者无参。
/*** findAll* */
def listAll = list.findAll()
println(listAll)def gl10All = list.findAll({a -> a > 100
})
println(gl10All)def all = list.findAll({item ->{return item == 10;}
})println(all)
2.2、find
list = [1, 1, 1, 1, 1]
def find = list.find({item ->{item == 1}
})
find:作用和findAll类似,但是find只会返回第一个符合条件的
2.3、findIndexOf
findIndexOf:返回满足条件的第一个元素的下标值。
3、返回新list
3.1、collect
collect:返回一个新的list,他可以接受一个闭包参数或者无参。
println("--------------collect---------------")
def collect = list.collect()
println(collect)def doCollect = list.collect({println("每一个it为:" + it)if (it == 10) {return it * it}return it - 1;
})println(doCollect)
3.2、tail
tail:返回一个新的list,它包含list中的所有的元素(除了第一个元素)
4、inject
inject:一个累积的过程方法(有点像js的reduce),传入inject方法中的ini作为sum的初始值,在遍历collection的过程中,讲处理结果(“$sum $elem”)保存到sum中。
list = ["love", "hello"]/*** "$elem $sum"可以理解为字符串的拼接,$sum作为起始值还是作为做后的值只需看他在$elem的前面还是后面* 如果$sum在后面说明每一次拼接新的元素都在最前面* 如果$sum在前面说明每一次拼接新的元素都在最后面* */def aa = list.inject("ini") {sum, elem -> "$elem $sum"
}println(aa)
5、each
和eachWithIndex
- each:普通的迭代遍历
eachWithIndex
:他的作用和each一样,但是他要传入一个闭包,有两个参数,一个是值,一个是索引。
list = [1233213, 312, 31, 23, 12, 31, 23, 12, 3, 123, 1, 24, 12, 4, 2435, 34, 5]
list.each({it -> println(it)
})list.eachWithIndex { int entry, int i ->{println(entry + "--------------" + i)}
}
6、every
every:接收一个闭包,返回为一个布尔值,当所有条件都满足时才返回true
def every = list.every(item -> {item > 0
})println(every)
7、any
any:和every的使用相同,只不过any的条件中只要有一个为真那么就返回真。
8、first
first:返回list的第一个元素
def first = list.first()
println(first)
9、last
last:返回list的最后一个元素
println(list.last())
println(list.lastIndexOf(10))
// 在原数组删除最后一个元素,返回为被删除的数据
def last = list.removeLast()
println(list)
println(last)
// 删除数组中最大的元素
def last1 = list.sort().removeLast()
println(last1)
10、groupBy、unique、max、min、count、sum等
def max = list.max()
println(max)println(list.min())
println(list.unique())
println(list.sum())
2.3.2、通配符
*:可以很方便的访问集合对象所有的属性
@TypeChecked
class Car {String makeString model
}def cars = [new Car(make: UUID.randomUUID().toString(), model: UUID.randomUUID().toString()),new Car(make: UUID.randomUUID().toString(), model: UUID.randomUUID().toString())
]def car_model = cars*.model
car_model.each {println(it)
}def numbers = 2..10.multiply(2) // Number:https://blog.csdn.net/u011422561/article/details/91353477
println(numbers)def upperCase = ["driver", "sky"]*.toUpperCase()
println(upperCase)
2.3.3、GPath
像Xpath语法一样可以轻松访问多层的集合对象。
a = [["a": 123],["a": 1],["a": 12]
]println(a.a.max())
2.3.4、IO操作
1、普通文件操作
// 创建文件并读取内容
def file = new File('./1.txt').text
println(file)// 如果没有当前文件就创建文件
def file1 = new File("./file.txt")
// 将内容写入文件
//file1.text = "123213dawd"String fileName = './file.txt'
// 通过字节的形式操作文件
def file2 = new File(fileName).bytes
println(file2)// 读取文件内容,然后一行一行的输出
new File(fileName).eachLine { line ->println(line)
}
2、InputStream操作
// 通过流的形式读取
def propertiesFile = new File('./test.properties') // 内容为:name=re
Properties properties = new Properties();
propertiesFile.withInputStream {properties1.load(it)
}def name = properties.name
println(name)
3、Reader操作
// 通过Reader进行文件的读取操作
def lineNo = 1
def line = 1;
new File(fileName).withReader {reader ->{while ((line = reader.readLine() != null)) {println("第${lineNo}行内容:${line} ----- ${reader.readLine()}")lineNo++;}}
}
4、Writer操作
基本操作
new File('./dwd.txt').withWriter('utf-8', {writer -> writer.writeLine('hello world')
})
精简版本
// Writer的精简版本
new File('精简版本.txt') << '''这是一个精简版本的文件new File('精简版本')
'''
5、操作Url
// Url操作
def text = "http://ww.baidu.com".toURL().text
println(text)
6、Ranges 用 … 表示范围
返回
// 操作返回
println((1..10)*.multiply(2))
println((10..1)*.multiply(2))('a'..'z').each { println(it) }
截取
text = "hello world"
println(text[0..2])(1..<6).each { println(it) }
2.3.5、工具
1、ConfigSlurper
ConfigSlurper
工具可以对读取配置文件十分方便
def config = new ConfigSlurper().parse('''app.data=new Date()'''
)def pp = config.toProperties()println(pp."app.data")
2、Expando
Expando
类是Groovy语言的一个相当有趣的类
他的作用类似于GroovyBean类,但是比他更灵活,同时他还类似于Map类,但也比Map更加灵活。
def expando = new Expando();
expando.name = { -> "abc" }
expando.say = {String s -> "${expando.name} say ${s}"
}def say = expando.say("hello")
println(say)def person = new Expando();person.name = "zhangsan"
person.age = 18person.des = {println("""-----------description-----------""")
}
person.des()
3、添加监听
def list = new ObservableList()
def printer = {e -> println(e.class)
}
list.addPropertyChangeListener(printer)
list.add('hello world1')
list.add('hello world2')
list.add('hello world3')
list.remove(0)
2.4、Java新特性
2.4.1、参数默认值
可以对定义的方法参数设置默认值
def func(args = "abc"){println(args);
}
2.4.2、注解
使用
@ToString
可以帮助用户提供运行时的数据信息。使用
@EqualsAndHashCode
注解可以使equals相等的两个对象的hashCode
也相等使用
@TupleConstructor
注解可以在传javaBean
的数据时,免去传key,直接传value@Canonical
注解时以上三个注解的合体。
2.4.3、正则表达式
只需要用 ~/表达式/, 匹配时用:需要匹配的字符=~/正则/;
def email = "2463983565@qq.com"
def isEmail = email ==~ /[\w.]/println(isEmail)
2.4.4、被弱化的泛型
@CompileStatic
class LsitS {List<String> list = ["123"];
}
2.4.5、Groovy的数字类型
在默认情况下groovy的数字类型都是BigDecimal类型,但是想要数字类型编程double,float,long类型的数字,只需要在数字后面加上c,f,l。
2.4.6、Boolean的自动转换
默认情况下groovy会把空字符串、0,null的if条件语句转成false,其他的转成true,这个特性和js、python一样
2.4.7、map语法糖
groovy允许我们把一个变量当做map的key或者value
def key = 1;
def value = 2;
def map = [(key): value]
println(map)
2.5、内置用法
2.5.1、自定义不存在方法的调用逻辑
class AAA {def methodMissing(String name, args) {println("没有这个方法")}
}def aaa = new AAA()
aaa.dw();
2.5.2、使用@Delegate
注解,可以实现方法的拷贝
class B{@Delegate final Person person; // 将person中的所有方法拷贝过来
}
2.6、DSLs
2.6.1、基本使用
- 可以通过
delegate
属性可以直接实现
package dslpublic class SMS {def form(String a) {println("from ${a}")}def to(String a) {println("to ${a}")}def body(String body) {println("body:${body}")}def bodyDSL(String dsl) {println("dsl:${dsl}")}def send() {println("send..........")}def static send(block) {def msm = new SMS();block.delegate = msm;block();msm.send()}
}SMS.send({form: "fromD"to: "toD"body: "I am body"
})
- 另一个dsl例子
show = { println(it) }sq_root = { Math.sqrt(it) }def please(action) {[then: {what ->[of: { n -> action(what(n)) }]}]}please(show).then(sq_root).of(100)
2.6.2、覆盖操作符
Operator | Method |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.multiply(b) |
a ** b | a.power(b) |
a / b | a.div(b) |
a % b | a.mod(b) |
a | b | a.or(b) |
a & b | a.and(b) |
a ^ b | a.xor(b) |
a++ | a.next() |
a– | a.previous() |
a[b] | a.getAt(b) |
a[index] = c | a.putAt(index, c) |
a << b | a.leftShift(b) |
a >> b | a.rightShift(b) |
a >>> b | a.rightShiftUnsigned(b) |
a >>> b | a.leftShiftUnsigned(b) |
switch(a){case (b): } | b.isCase(a) |
if(a) | a.asBoolean() |
~a | a.bitwiseNegate() |
-a | a.negative() |
+a | a.positive() |
a as b | a.asType(b) |
a == b | a.equals(b) |
a != b | !a.equals(b) |
a <=> b | a.compareTo(b) |
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a >= b | a.compareTo(b) >= 0 |
a <= b | a.compareTo(b) <= 0 |
2.6.3、操作属性get|set
class MyList {def list = [1, 2, 3, 4]def setAt(Integer a) {this.list.add(a)}
}MyList l = new MyList();
def list = l.getList()
println(list)
2.6.4、魔法方法
class MyList {def propertyMissing(String name) {println("属性:${name}不存在")}def methodMissing(String name) {println("方法:${name}不存在")}}
2.7、trait关键字
traits关键字相当于jdk8的接口类,可以实现默认方法。也可抽象方法。
- 如果定义抽象方法时,要加上abstract关键字
- 可以实现具体的方法
2.8、函数式编程
2.8.1、基本使用
list = [1, 2, 4, 6, 8]// 函数和闭包
static def finds(list, tester) {for (item in list) {if (tester(item)) {return item}}
}def i = finds(list, {it > 2
})println(i)
2.8.2、@Immutable
注解 (类似final)
放在类上,可以对所有的属性进行final的操作相同。
2.8.3、利用groovy的迭代方法进行流畅操作
// 批量截取字符串
list = ["dwawa", "dwawa", "dwawa", "dwawa"]
def collect = list.collect(it -> {it.substring(1)
})
println(list)
println(collect)// 判断若干个对象的name的谁的最长
def student1 = new Student("31233123123123")
def student2 = new Student("3123123123")
def student3 = new Student("3123213123dsa3123")list = []
list.add(student1)
list.add(student2)
list.add(student3)def studentName =list.findAll((item) -> { item.name != null }).collect((item) -> { item.name }).inject("") { n1, n2 ->{n1.length() >= (((n2 as String).length()) as Integer) ? n1 : n2}}
println(studentName)
2.8.4、curry(咖喱)方法
可以预设一些参数
con = { x, y -> return x + y }
br = con.curry("dwa")println(br("x"))// 返回值为dwax
2.8.5、业务处理逻辑
class A {static print(name) { println("${name}") }
}[1, 2, 3, 4, 4, 5].each { A.print(it) }
2.8.6、防止递归溢出
@TailRecursive
// 这个注解会将方法放入堆里面,而不是压栈
由浅入深的了解Groovy的基本使用相关推荐
- nifi DBCPconnectpool 连接oracle 死链接
nifi DBCPconnectpool 连接oracle 死链接 问题展示 问题解决 后言 官网 中文网 Groovy脚本学习 问题展示 原因,nifi 连接oracle因为网络波动出现死链接,我的 ...
- Idea groovy表生成实体类带注释
Idea groovy表生成实体类带注释 1.点开datasourse,打开idea带的数据库工具,具体添加数据库连接,这里不描述. 这时点击会生成一个poji 这时生成的pojo中是不带中文注释的, ...
- groovy–流程控制
在本篇文章中,我们将介绍逻辑分支,循环,以及如何从if-else以及try-catch代码块中返回值. if – else Groovy 支持Java传统的if-else语法: def x = fal ...
- groovy–运算符重载
Groovy支持运算符重载,各种运算符被映射到普通的java对象的方法调用,这就使得开发者可以利用运算符重载的优势来编写自己的Java或者groovy对象. 下面的表格描述了groovy中的操作符所映 ...
- 便捷,轻巧的Groovy数据库操作
本文主要介绍Groovy对数据的CRUD操作,熟悉groovy.sql包,测试使用的数据库是H2. 1.数据库连接配置 //数据库连接配置 def db = [url:'jdbc:h2:mem:gro ...
- DBA入门之路:由浅入深的总结学习法
有很多DBA朋友在入门时总觉得不得路径,长久的徘徊于门外,而过来人的经验又往往高屋建瓴难以落地,两者总觉得难以对接起来,如何才能解决这个问题呢? 我一直推荐的学习方法,之前在文章 DBA入门之路:学习 ...
- ElasticSearch Groovy脚本远程代码执行漏洞
什么是ElasticSearch? 它是一种分布式的.实时性的.由JAVA开发的搜索和分析引擎. 2014年,曾经被曝出过一个远程代码执行漏洞(CVE-2014-3120),漏洞出现在脚本查询模块,由 ...
- java ee不能运行_Java9+移除 Java EE,导致我的 groovy 脚本无法运行
以以下这段代码为例 @Grab('org.jsoup:jsoup:1.10.1') import org.jsoup.Jsoup Jsoup.connect('https://v2ex.com').g ...
- TIOBE 2月编程语言排行榜:Python逼近C,Groovy重回TOP 20
作者 | 唐小引 出品 | CSDN(ID:CSDNnews) 新月伊始,一月一更的 TIOBE 编程语言社区发布了最新的 2 月编程语言排行榜. 继 Python 语言成为 "2018年度 ...
- Groovy基本句法
Gradle作为一个构建工具自然不会自己去创造一门语言来支撑自己,那么它用的是哪门子语言呢?什么语言能写成这样: task hello {doLast {println 'Hello world!'} ...
最新文章
- Java切面理解_Spring AOP面向切面编程:理解篇
- VSCODE常用开发环境配置----保存
- 将一个Excel文件分隔成多个
- Windows 技术篇-设置电脑启用或禁用开机按Ctrl+Alt+Del解除锁定
- 周报速递丨小红书提出 IDEA 方法论;金融业七大数字化趋势
- leetcode 两个数组的交集 II
- 理顺 JavaScript (7) - 数字相关问题
- addressof表达式不能转换为long_2.3 C++赋值运算符与表达式 | 将有符号数据赋给无符号...
- 前后端分离登录验证功能实现案例
- Powershell 美化,FluentTerminal.Package_0.6.1.0_Test安装设置及卸载教程
- 单龙芯3A3000-7A1000PMON研究学习-(3)初步编译
- Keil5下载烧录错误常见问题
- 原型设计工具Axure
- 观史图馆之《中东列国历代疆域变化 青铜与古典时代》
- centos6添加系统服务
- CAJViwer安装提示:请求的操作需要提升
- 源码解析zxing条码边距及总宽度计算规则,附java使用zxing生成条形码,并去除条码两边空白
- 使用github免费搭建个人网站详细教程
- 从产品角度分析羊了个羊为何能爆火
- 学生php作业,作业作业作业作业作业