groovy中的闭包及常用方法
发布时间:2020-12-14 16:42:53 所属栏目:大数据 来源:网络整理
导读:Groovy是增强Java平台的唯一的脚本语言。它提供类似于Java的语法,内置映射(Map)、列表(List)、方法、类、闭包(closure)以及生成器。 Groovy是动态弱类型语言,即Groovy不要求声明变量的类型、方法的参数或者方法的返回值。这意味着在不同环境下,变量
|
Groovy是增强Java平台的唯一的脚本语言。它提供类似于Java的语法,内置映射(Map)、列表(List)、方法、类、闭包(closure)以及生成器。
Groovy是动态弱类型语言,即Groovy不要求声明变量的类型、方法的参数或者方法的返回值。这意味着在不同环境下,变量可以以多种方式使用。 Groovy类和Java是二进制兼容的。这意味着Groovy编译器产生的字节码与Java编译器产生的字节码是完全一样的。因此,对JVM而言,Groovy和Java是完全一样的。 Groovy是一门面向对象的语言。 数值和表达式 两个整数的除法运算通常会产生一个浮点数,即使其结果可能是一个整数。 如表达式6/3的结果是浮点数2.0,而不是整数2. 为了获得两个整型值相除的整数部分,必须调用intdiv方法: 13.intdiv(5) 该表达式的结果是整数2. 使用取模运算符(%)可以得到两个整数操作数相除的余数。但是对一个浮点数求模,或者对一个含有浮点数参数的整数求模都是非法的。 在Groovy中,第一次使用某个变量时,需要使用def关键字来声明变量。 变量的命名规则:可以由字母、数字和下划线组成,对大小写敏感,首字符必须是字母。 字符串和正则表达式 在Groovy中,可以使用单引号('abc')、双引号("abc")、或者三引号('''abc''')来封装字符串。使用三引号表示的字符串可以包含多行文本。 使用单引号封装的字符串的值就是所列出的字符序列本身。而在双引号和三引号中,任何包含在解释型字符串中的${expression}都将被求值, 其结果是字符串的一部分。如: def age = 25 'My age is ${age}' ? ? ?//My age is ${age} "My age is ${age}" ? ? ?//My age is 25 '''My age is ${age}''' ?//My age is 25 "My age is ${age}" ? ? //My age is ${age} 通用的原则是,只在字符串需要被解释的时候使用双引号,在其他情况下字符串使用单引号。 闭包常用方法demo,直接贴代码demo.groovy,运行时直接输入groovy demo.groovy:
// groovy中的闭包及常用方法
// 闭包的两种写法:
// 1. 有参数的闭包:def clos = {参数名 -> 代码块}
// 2. 无参数的闭包:def clos = {代码块}
/****************************************************/
def hello = 'Hello'
def clos = {
param -> println "${hello},${param}"
}
def clos2 = {
p1,p2 -> println "the parameters are ${p1} and ${p2}"
}
def demo(clo) {
clo('zyf')
}
// 闭包的调用方式
clos.call("zyf")
clos('zyf')
clos'zyf'
clos2(1,2) // 也可以写成:clos2 1,2
// 参数有闭包的方法的调用方式
demo(clos)
demo clos
demo{
param -> println "hello,${param}"
}
/********输出结果********/
//Hello,zyf
//Hello,zyf
//the parameters are 1 and 2
//Hello,zyf
//hello,zyf
/********输出结果********/
/****************************************************/
// upto方法无参数时表示循环几次(如:从1循环到3),有参数时,参数从几递增到几(如:从3递增到4)
1.upto(3) {
println "abc"
}
def count = 0
3.upto(4) {
p -> count += p
}
println "count: ${count}"
/********输出结果********/
//abc
//abc
//abc
//count: 7
/********输出结果********/
/****************************************************/
// each方法常常用于列表、映射和字符串,以遍历每个元素,并将闭包应用于每个元素
[1,2].each {
println it
}
['zhangsan' : 21,'lisi' : 22].each {
println it
}
['zhangsan' : 21,'lisi' : 22].each {
println "${it.key} maps to : ${it.value}"
}
['zhangsan' : 21,'lisi' : 23].each {
p -> if (p.value > 22) {
println "${p.key} value over 22"
} else {
println "${p.key} value low 23"
}
}
/********输出结果********/
//1
//2
//zhangsan=21
//lisi=22
//zhangsan maps to 21
//lisi maps to 22
//zhangsan value low 23
//lisi value over 22
/********输出结果********/
/****************************************************/
// find方法返回集合中符合某个判断标准的第一个值,若不存在则符合null。在闭包中,集合元素使用的判断条件必须是布尔表达式。
def f = [1,2].find {
it -> it > 1
}
println "find : ${f}"
/********输出结果********/
//find 2
/********输出结果********/
/****************************************************/
// findAll方法将遍历所有元素,并返回一个符合条件的列表。
def fa = ['zhangsan' : 21,'lisi' : 23,wangwu : 24].findAll {// map的key默认都是字符串,故可以不用单引号或双引号
it -> it.value > 22
}
println "find all : ${fa}"
fa.each {
println it
}
[1,2,3].findAll {
it -> it > 1
}.each {
println it
}
/********输出结果********/
//find all [lisi:23,wangwu:24]
//lisi=23
//wangwu=24
//2
//3
/********输出结果********/
/****************************************************/
// any方法将遍历检查集合的每个元素,以确认:对至少一个元素来说,由闭包提供的布尔断言是否合法。
def a = [1,2].any {
it -> it > 1
}
println "any one over 1? ${a}"
/********输出结果********/
//any one over 1? true
/********输出结果********/
/****************************************************/
// every方法则用来检查:对集合的所有元素来首,闭包提供的布尔断言是否合法。
def e = [1,2].every {
it -> it >1
}
println "every one over 1? ${e}"
/********输出结果********/
//every one over 1? false
/********输出结果********/
/****************************************************/
// collect方法将遍历某个集合,并使用闭包中的变换方法将集合中的每个元素转换为一个新值。返回一个由转换后的值所组成的列表。
def list = [1,3,4].collect {
it -> return it * it
}
println "list: ${list}"
list = (0..2).collect {// ..表示范围,从start到end的值,这里表示(0,1,2)
it -> 2 * it
}
println "list:${list}"
list = (0..<2).collect {// ..<也表示范围,但是不包含右边界值,这里表示(0,1)
it -> 3 * it
}
println "list:${list}"
def s = ['zhangsan' : 21,'lisi' : 22]
list = s.collect {
it -> ++it.value
}
def olderS = s.collect {
it -> ++it.value
return it
}
println "s : ${s}"
println "list : ${list}"
println "olderS : ${olderS}"
/********输出结果********/
//list: [1,4,9,16]
//list:[0,4]
//list:[0,3]
//s : [zhangsan:23,lisi:24]
//list : [22,23]
//olderS : [zhangsan=23,lisi=24]
/********输出结果********/
/****************************************************/
// inject方法可用于遍历集合,首先将需要传递的初始值和集合项目传递给闭包,此时其传递的初始值将作为初始结果,
// 然后再和下一个集合元素一起传给闭包,以此类推。
def factorial = [2,4].inject(1) {
previous,element ->
println "pre: ${previous},ele: ${element}"
previous * element // 这里的previous分别是上次计算的结果值1,6;element分别是集合元素2,4
}
println "Factorial(4) : ${factorial}"
/********输出结果********/
//pre: 1,ele: 2
//pre: 2,ele: 3
//pre: 6,ele: 4
//Factorial(4) : 24
/********输出结果********/
/****************************************************/
// 闭包作为返回值
def multiply(x) {
return {
y -> return x * y
}
}
def twice = multiply(2)
println "twice(3) = ${twice(3)}" // 这里的twice(3)相当于multiply(2)(3),后面的3是传递给作为返回值的闭包的参数
/********输出结果********/
//twice(3) = 6
/********输出结果********/
/****************************************************/
// 冒泡排序
def swap = {
sList,p,q ->
def temp = sList[p]
sList[p] = sList[q]
sList[q] = temp
}
def minPosition = {
pList,from ->
def mPos = from
def nextFrom = from + 1
for (i in nextFrom..<pList.size()) {
if (pList[i] < pList[mPos]) {
mPos = i
}
}
return mPos
}
def selectionSort = {
l ->
def size = l.size() - 1
for (j in 0..<size) {
def minPos = minPosition(l,j)
swap(l,minPos,j)
}
return l
}
def table = [2,3]
def sorted = selectionSort(table)
println "sorted : ${sorted}"
/********输出结果********/
//sorted : [1,4]
/********输出结果********/
/****************************************************/
/****************************************************/
// 文件操作
println "str's length:" + "a c d d".tokenize().size() // tokenize切分词返回列表,如[a,c,d,d]
/********输出结果********/
//str's length:4
/********输出结果********/
/****************************************************/
// File类提供了eachFile方法,用来表示某个目录的文件对象,它接收闭包作为其参数,且对该目录中每个文件调用此闭包
def listDir(dirFile,indent) {
dirFile.eachFile {
file ->
(0..<indent).each {
print " "
}
println "${file.getName()}"
if (file.isDirectory()) {
listDir(file,indent + 2)
}
}
}
def printDir(dirName) {
listDir(new File(dirName),0)
}
// 命令行调用时,参数跟在文件名后,如:groovy demo.groovy c:Users...Desktop
/*
if (args.size() != 1 || new File(args[0]).isDirectory() == false) {
println "please enter a directory"
} else {
printDir(args[0])
}
*/
/****************************************************/
// File类提供了eachFileRecurse方法,它可以遍历某个目录中的所有文件,并且递归遍历子目录
def printDir2(dirName,size) {
new File(dirName).eachFileRecurse {
file ->
if (file.getName().size() > size) // 遍历查找文件名大于给定长度的文件
println "the file ${file.getName()} name's size over ${size}"
}
}
/*
if (args.size() != 2 || new File(args[0]).isDirectory() == false)
println "please enter 2 right args!"
else
printDir2(args[0],args[1].toInteger())
*/
/****************************************************/
// xml解析
// 文件library.xml的内容:
//<library>
// <book>
// <title id='111'>java</title>
// </book>
// <book>
// <title id='222'>c</title>
// </book>
//</library>
def doc = new XmlParser().parse('library.xml')
println "${doc.book[0].title.text()}"
doc.book.each { // 遍历每一个book节点
it -> println "${it.title.text()}"
}
doc.book.title.each { // 遍历每一个book节点的每一个title节点
it -> println "${it.text()}"
}
println doc.book.title[0]['@id']
println doc.book.title['@id']
/********输出结果********/
//java
//java
//c
//java
//c
//111
//[111,222]
/********输出结果********/
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
