groovy笔记

groovy是动态语言,是在运行时,进行语言调用检查的。而Java是编译时的语言,代码在编译时进行调用检查的。
1、基本类型
(1)String类型

单引号与双引号的区别 (使用闭包时候惰性求值)
多行字符串
对字符串类型的一些扩展
(execute、find)

  1)def k = 'a' 或者 def k = "a"   //这里k都是String类型,不是char类型(与Java不一样)
  2)def k = 'a' as char   //此时k是char类型,as是重新指定类型
  3)字符串的拼接
     def k = 'a' as char
     def i = "Gro${k}ovy"(这里必须使用双引号"")
     println i     //  最终输出结果是  Groaovy

    闭包形式
	def j = "Gro${->k}ovy"
	k = 'b'
	println j    //  最终输出结果是  Grobovy
 
  4)多行字符串
  	Java中的字符串换行\n等价于groovy中的""""""
  	如 "java\ngroovy" 等价于  
  	"""java
  	groovy"""
  	最终输出结果都是  
  	java
  	groovy

  5)取值
	  "groovy"[0]  // 输出 g
	  "groovy" - 'vy'    //输出 groo

 6)支持	  execute()
 	 println "cmd /c groovy -v".execute().text
 	 指在Terminal中输入"groovy -v"命令,并将结果以String的形式输出


 7)判断条件
 	"".asBoolean()   //只要是字符串长度length>0,则返回true,否则返回false
 	if(""){}   //对于if条件判断,也是如此,只要是字符串长度length>0,则true。这个与Java不一样。

 	同样,对于Number类型的,如int、float、double,也有此特性
 	6.asBoolean()  //只要Number!=0,则返回true,否则返回false
 	if(6){}   //对于if条件判断,也是如此,只要Number!=0,则true。这个与Java不一样。

8)比较
  比较地址: Java中用 "==",等价于groovy中的 is
  比较值: Java中用 "equals",等价于groovy中的 "=="

  9)groovy中 "=~" 等价Java中的  "contains" 

10)split
	可以指定split后,接收结果的属性。但是,指定接收的属性的个数不能大于str.split()后数组的长度
 	def str = 'org.codehaus.groovy:groovy-all:2.4.9'
	def (group, name, version,classifier) = str.split(":")
	//group ===> org.codehaus.groovy    , name  ===> groovy-all, version ===>2.4.9  

2、循环

IntRnage i…j(0…9)
times/downto/upto/step

1)in IntRange()
for (i in new IntRange(0,9)){
print i + " "
}
//输出 0 1 2 3 4 5 6 7 8 9

2)for (i in 0…9){
print i + " "
}
//输出 0 1 2 3 4 5 6 7 8 9

for (i in 0..<9){
	print i + " "
} 
//输出  0 1 2 3 4 5 6 7 8 

3)times
10.times {
print it + " "
}
//输出 0 1 2 3 4 5 6 7 8 9

4)step
10.step(5,-2){
print it + " "
}
//输出 10 8 6
分析: 10每次加上-2,直到结果<5,停止输出

2、数组集合
(1)取值
def list = [“1”,“2”,“3”,“4”,“5”]
println list[-2] //不会越界,负数就是从后往前取值,即输出 4
println list[9] //不会越界错误,null
println list[1…3] //输出 [2, 3, 4],注意:返回的数组是一个新的数组

(2)数组遍历
1)each
def list2 = list.each {
print it + " "
it * 2
}
println list2
//输出结果 :1 2 3 4 5 [1, 2, 3, 4, 5]
2)collect
def list2 = list.collect {
print it + " "
it * 2
}
println list2
//输出结果 :1 2 3 4 5 [11, 22, 33, 44, 55]

	总结:	each与collect的区别,
	       a.相同点:都可以在闭包内部输出各个元素,返回值也可以用集合接收
	       b.不同点:collect在遍历的时候,可以修改每个元素的值,并且返回,而each不可以

	3)reverseEach 反向遍历       	
		 list.reverseEach {
		    print it + " "
		}
		//输出结果 :5 4 3 2 1


	4)eachWithIndex
		list.eachWithIndex{ String entry, int i ->
		    println entry + " ==>" + i
		}

		输出结果:   1 ==>0
					2 ==>1
					3 ==>2
					4 ==>3
					5 ==>4

	5)查找集合中的元素find、findAll
	 	println list.find{
		    it == "2"
		}
		输出结果:  2
		若没有查找到,返回值是null

		findAll 返回结果以数组的形式表示,返回所有满足条件的元素

	6)"-"移除所有元素,"+"添加元素
	    def  list = ["1","2","3","4","5","3"]
		def  list3 = list - "3"
		println  list3          //[1, 2, 4, 5]
		println  list3 + "300"  //[1, 2, 4, 5, 300]

		注意:操作后,返回的是一个新的集合。如果是对原有集合list操作,则用<<

	7)<<,对原有集合list添加元素操作
	   def  list = ["1","2","3","4","5","3"]
	   println  list + "300"
	   println list <<[100,200]
	   //输出结果:  [1, 2, 3, 4, 5, 3, 300]
					[1, 2, 3, 4, 5, 3, [100, 200]]

	问题:def  list = [1, 2, 3, 4, 5, 3, [100, 200]]拉平?
	  	println list。flatten()		
	  	 //输出结果:[1, 2, 3, 4, 5, 3, 100, 200]

	8)展开操作  	 list*.
		def lst = ['java','groovy','cpp','oc']
		println lst*.toUpperCase()   //输出结果:[JAVA, GROOVY, CPP, OC] , lst*是先展开数组lst,然后再toUpperCase()转为大写

	9)	any、every  返回值都是boolean
		def lst = ['java1','groovy1','cpp1','oc1']
		println lst.any{
		    it == "groovy1"
		}
		//输出结果:true  ,判断lst数组中是否有元素是"groovy1"

		println lst.every{
		    it =~ "1"
		}
		//输出结果:true  ,判断lst数组中所有的元素都包含"1",只要一个元素不包含,就返回false

3、map集合
1)定义
def map = [B: ‘Baidu’, ‘A’: ‘Alibaba’, T: ‘Tencent’]

2)取值,总共三种方式
	println map.A
	println map['A']
	println map.'A'
	//	输出结果:Alibaba

3)遍历
	map.each {
	    key, value ->
	        println "${key}=${value}"
	}

3)查找
	println map.find {    //查找value中包含'a'
	    key,value->
	        value =~ 'a'
	}

	//	输出结果:[B:Baidu]  ,如果是findAll,则返回全部的[B:Baidu, A:Alibaba] 

4)println map*.getKey()  //返回所有的key   [B, A, T]

4、闭包
(1)柯里化闭包
def closure = {
i, j ->
println i + ’ ’ + j
}
def curriedClosure = closure.ncurry(1,‘Groovy’)
curriedClosure(‘java’)
// 输出 java Groovy

(2)对一个对象上调用() 表示调用这个对象上的call方法
class Action1{
def call(){
println ‘call’
}
}

	new Action1()()  等价于  new Action1().call()

(3)关于this、owner、delegate的区别
class ClosureDemo {
def closure1 = {
def closure2 = {
println "this is " + this
println "owner is " + owner
println "delegate is " + delegate
}
closure2()
}
}
new ClosureDemo().closure1()

// 输出
this is ClosureDemo@3214ee6
owner is ClosureDemo c l o s u r e 1 @ 383 d c 82 c d e l e g a t e i s C l o s u r e D e m o _closure1@383dc82c delegate is ClosureDemo closure1@383dc82cdelegateisClosureDemo_closure1@383dc82c

总结:
	this 定义它的时候 所在的类的对象 静态闭包当中为 类的class
	owner 定义它的时候 所在类的对象
	delegate 默认就是owner

(4)delegate代理的使用
class TestFunc {
def func() {
println ‘TestFunc:func’
}
}
def closure = {
func()
}
closure()
上述调用结果是失败的。因为闭包closure中调用的func()方法是在TestFunc类中的。如果要正常调用,可以使用delegate代理,具体做法是:
closure.delegate = new TestFunc()
closure()

代理策略:
	1、Closure.OWNER_FIRST
	2、Closure.DELEGATE_FIRST
	3、Closure.TO_SELF
   class TestFunc {
	    def func() {
	        println 'TestFunc:func'
	    }
	}
	def func() {
	    println 'listener4_1:func'
	}
	def closure = {
		 def func = {
        	println 'closure:func'
    	}
		func()
	}
	closure.delegate = new TestFunc()
	closure.resolveStrategy = Closure.OWNER_FIRST
	closure()

	输出结果: 
	1)closure.resolveStrategy = Closure.OWNER_FIRST  // listener4_1:func
	2)closure.resolveStrategy = Closure.DELEGATE_FIRST  // TestFunc:func
	3)closure.resolveStrategy = Closure.TO_SELF  // closure:func

5、构造函数
Groovy 提供了更加灵活方便的构造函数
例如:
class Person {
def name
def age

    def getName() {
        return name + '_'
    }

    void setName(name) {
        this.name = name
    }

    def execute(x, y, z) {
        println "$x $y $z"
    }
}

(1)设置Person属性值
def person = new Person(name: ‘Jack’) //传入的参数可以任意指定属性的值,其实,因此,不需要向Java中一样设置那么多Person的构参
person.name = ‘Jack’

(2)获取Person属性值
1)println person.name
2)person.name = ‘Jack’
println person.name
3)println person.‘name’
4)def str = ‘name’
println person.“$str”
5)println person[‘name’]

以上输出结果都是 Jack_  ,原因是获取name属性时,其实是默认的调用了getName()方法

如果想要直接使用成员 那么需要使用@符号
person.name = 'Jack'
println person.@name   //输出结果 Jack

(3)函数中的参数,含有map
person.execute(4,x: 1, y: 2, z: 3,5) // 输出 {x: 1, y: 2, z: 3} 4 5
调用函数时,如果传递的参数中带有map类型(如上述的x: 1, y: 2, z: 3),不管这个map参数是放在什么位置,始终会将这个map类型默认赋值给函数的第一个参数

(4)调用函数时 如果需要传递一个接口,那么可以使用闭包来代替 as能够将闭包转换成函数需要的接口对象
例如:
interface OnClickListener {
void after()
void doing()
void before()
}
OnClickListener listener = {
println “hello”
} as OnClickListener //用as声明

listener.doing()
listener.after()
listener.before()

6、扩展方法:
(1)创建扩展类并实现扩展方法:
class XXXExtension {
static void [methodName]([扩展的类] self[,params]) {

}
}

(2)添加配置文件(META-INF/services/org.codehaus.groovy.rumtime.ExtensionModule):
moduleName=myModule (扩展模块名)
moduleVersion=1.0 (模块版本)
extensionClasses= XXXExtension (需要扩展的实例方法所在的类)
staticExtensionClasses= XXXExtension (需要扩展的静态方法所在的类)
注意:
<1>以上不管是实例方法(extensionClasses)、还是静态方法(staticExtensionClasses),在XXXExtension 类中申明的扩展类方法必须都是静态的。
<2> 编译、打包指令
1)将FileExtension.groovy 文件编译 到classes目录下
groovyc -d groovyLib/src/main/groovy/classes C:\Users\hailinhe\Desktop\gradleDemo\test2\groovyLib\src\main\groovy\FileExtension.g
roovy
2)将classes和manifest目录下的所有文件,打包为jar包
jar cvf file.jar -C groovyLib/src/main/groovy/classes/ . -C groovyLib/src/main/groovy/manifest/ .

7、语言特性
动态类型语言中的类型,在编译期不检查,而是在运行时判断的,方法以及其实参也是在运行时检查的。

	    @TypeChecked
		class TestClass{
		    void func(person) {  //由于类上声明了TypeChecked,所以这里会报错,参数person没有指定具体的类型
		        person.dream()
		    }

		    @TypeChecked(TypeCheckingMode.SKIP)
		    void func2(person) {   					//由于声明了TypeCheckingMode.SKIP,跳过编译检查,所以这里不会报错
		        if (person.respondsTo('dream'))			//person中是否有dream的方法
		            person.dream()
		    }
		}

(0)在groovy中,方法中,可以不指定具体的参数,也可以调用
    new TestClass().func(new Lance())
	new TestClass().func(new Person())
	new TestClass().func('')		
(1)TypeChecked
	可以作用在类上、构参、方法上。当设置该注解时,代码在编译期间是否检查。
	有两个值,分别是TypeCheckingMode.PASS,默认值,需要检查。TypeCheckingMode.SKIP跳过检查。
	例如:


(2)respondsTo
(3)hasProperty
	new Lance().hasProperty('name')   //Lance对象中是否有 name 属性
(4)CompileStatic	
  同时由于使用动态节点调用,损耗性能,可以使用CompileStatic开启静态编译。

8、脚本的调用
场景:在不同场景下,调用groovy目录下的 test1.groovy 脚本文件
(1)脚本文件中调用脚本
def name = ‘123’ //本地作用域,相当于局部变量,私有成员
/********************* 设置参数 *************************/
str = “来自script调用” //绑定作用域,在"test1.groovy"脚本文件中,可以使用该参数。相当于全局变量
list = [“groovy1”,“groovy4”,“groovy3”,“groovy4”]
args = [] //先定义一个空数组
args[0] = “test1.groovy” //指定参数,这里是"test1.groovy"
evaluate(new File(“test1.groovy”)) //执行脚本文件

(2)groovy中调用脚本
         static void main(args){
		     def binding = new Binding()
		     /********************* 设置参数 *************************/
		     binding.setVariable("list",["groovy1","groovy4","groovy3","groovy4"])
	         binding.setVariable("number",500);
	         binding.setVariable("str","groovy调用脚本")
	         binding.setProperty("phoneNum",600)
		     GroovyShell shell = new GroovyShell(binding)
		     shell.evaluate(new File("src/main/groovy/test1.groovy"))  //运行脚本文件,路径需要是文件全路径
		  }  

(3)java中调用脚本
    public static void main(String[] args) throws IOException{
        Binding binding = new Binding();
        /********************* 设置参数 *************************/
        binding.setVariable("list",new String[]{"java1","java2","java3","java4"});
        binding.setVariable("number",50);
        binding.setVariable("str","java调用脚本");
        binding.setProperty("phoneNum",100);
        GroovyShell shell = new GroovyShell(binding);
        shell.evaluate(new File("src/main/groovy/test1.groovy"));		//运行脚本文件,路径需要是文件全路径
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值