加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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]
/********输出结果********/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读