基本类型
其实在 Groovy 中是没有基本类型的,例如下所示:
int x = 10; println(x.class)
打印结果如下:
class java.lang.Integer
可以看到他是一个 Integer 对象。其实在底层编译的时候已经将 int 装箱成了 对象。
变量的定义
groovy 定义变量有两种方式,分别是 强类型定义 和 若类型定义,强类型定义和 java 中的意义,但是弱类型定义是什么呢,如下:
//强类型定义方式 int x = 10; println(x.class) //弱类型定义方式 def x1 = 1; println(x1.class) def x2 = 3.14; println(x2.class) def x3 = "Android" println(x3.class)
结果如下:
class java.lang.Integer class java.lang.Integer class java.math.BigDecimal class java.lang.String
第二行 是大数据类型
其实弱类型定义就是不指定具体的类型。通过值来确定它到底是什么类型。用 def 来定义
如何选择呢?如果在本类中使用,则建议使用 def 类型。但是别的类也要用到这个变量。则尽量使用强类型定义;def 声明的变量类型可以随时改变,如 x1 是 Integer 。如果给 x1 赋值为 String,这样他就会变为 String。正是这个原因所以才不建议在 别的类使用这个变量时定义为 def。
字符串
常用的定义方式:
//1,通过 单引号定义String ,和双引号没有任何区别 ,转义 '单引号 \'String \'' def name = '单引号 String' println(name) //2,通过三个单引号定义String ,但定义的格式进行输出, def name1 = '''第一行 第二行 第三行''' println(name1) // 3,双引号 ,可扩展字符串,扩展后使用的不是String,而是GString类 def name2 = "双引号" def hello = "hello ${name2}" println(name2) println(hello.class) //可扩展字符串使用 ,可以扩展任意的表达式 def sum = "sum = ${5 - 6 - 6 + 12}" println(sum) def result = echo(sum) println(result) String echo(String message){ return message; }
通过上面这几种方式可以 定义字符串,其实一般最常用的就是 第三种了。注意扩展后的字符串就不是 String。而是 GString。不信的话可以打印看一下。
字符串方法
字符串的方法
1,第一种就是String类原有的方法
2,第二种则是 DefaultGroovyMethods ,是 Groovy 对所有对象的扩展
3,第三种是 StringGroovyMethods ,继承自 DefaultGroovyMethods 。
重点要看的是 StringGroovyMethods 。他继承自第二种,第一种是 String,比较熟悉。
首先定义一个字符串:
String str = "哈哈哈"
填充
println str.center(8, 'a') //填充: aa哈哈哈aaa println str.padLeft(8, 'a') //填充:aaaaa哈哈哈
比较
println str > "嘻嘻嘻" //通过运算符比较字符串大小 :false
索引
println str.getAt(0) //下标为0 :哈 println str[0] //通过类似于数组的方式来获取 :哈 println str[0..1] //指定范围 :哈哈
减法
println str.minus("哈哈") //减法 : 哈 --减去两个剩一个 。 println str - "哈哈";
倒序
println str.reverse()
首字母大写
println str.capitalize()
判断 str 是否为数字类型
println str.isNumber()
转为基本数据类型
println str.toInteger() println str.toBoolean() println str.toDouble()
其实方法还有很多,这里就不一一列举了。
可查看文档
控制语句
switch:groovy 中的 switch 和 java 中的有明显的不同,它可以接受任意的数据类型。如下:
// switch ,可以传入任意类型的数据 def x = 1.23 def result; switch (x) { case '哈哈哈哈': result = '0' break case '嘻嘻': result = '1' break case [4, 5, 6, 'inlist']: //列表 result = '2' break case 12..30: //范围 result = '3' break case Integer: result = '4' break case BigDecimal: result = '5' break default: result = 'defalut' break } println result //5
for 循环
// 对范围的 for 循环 def sum = 0 for (i in 0..9) { sum += i } println sum //对 list 进行循环 sum = 0 for (i in [1, 2, 3, 4, 5, 6, 7, 8, 7]) { sum += i } println sum //对 map 进行循环 sum = 0; for (i in ['one': 1, 'two': 2, "three": 3]) { sum += i.value } println sum; // 45 // 43 // 6
闭包
基础详解
闭包是一个开放的,匿名的代码块,可以带参数,返回一个值。可以通过一个变量引用到他,也可以传递给别人进行处理。
闭包的创建和调用
def clouser = { println "hello groovy" } //两种方式调用闭包 clouser.call() // hello groovy clouser() // hello groovy
创建带参数的闭包和调用
def clouser = { //箭头前面是参数,后面是闭包体 String name, int age -> println "hello groovy ${name} -- ${age}" } //调用带参数闭包 clouser.call("张三", 32) // hello groovy 张三 -- 32 clouser("李四", 23) //hello groovy 李四 -- 23
默认参数
//每一个闭包都有一个默认的 it 参数,如果不想使用,则显示的定义即可。 def clo = { println "hello ${it}" } clo.call("李四") //hello 李四
闭包返回值
def clouser = { //箭头前面是参数,后面是闭包体 String name, int age -> return "hello groovy ${name} -- ${age}" } //调用带参数闭包 println clouser.call("张三", 32) //hello groovy 张三 -- 32
使用详解
基本类型结合使用:
阶乘
int x = 5 println fab(x) //求 number 的阶乘 int fab(int number) { int reslut = 1 //调用 upto 方法,传入 number 和 闭包 ,闭包中有一个 num 参数 1.upto(number, { num -> reslut *= num }) return reslut } //结果:120
为什么要这样写呢?看一下源码秒懂!
//打眼一看这里需要三个参数,我们只传了两个?,注意:1.upto()中的 1,代表的是第一个参数, public static void upto(Number self, Number to, @ClosureParams(FirstParam.class) Closure closure) { //拿到开始的位置和结束的位置 int self1 = self.intValue(); int to1 = to.intValue(); //小于等于 if (self1 <= to1) { for (int i = self1; i <= to1; i++) { //调用传入的闭包,将i 传进去,从这里就可以知道我们写的闭包为啥要一个 num 的参数了。 closure.call(i); } } else throw new GroovyRuntimeException("The argument (" + to + ") to upto() cannot be less than the value (" + self + ") it's called on."); }
阶乘2
int fab2(int number) { int result = 1 number.downto(1) { num -> result *= num } return result } //结果:120
你知道 downto 方法传入了几个参数吗。。。。没错,是3个,number是一个,1 是一个,括号外面的闭包是一个。闭包写在括号外面和写在里面效果完全一样。这个是倒着来的。具体的可以查看源码。
累加
int cal(int number) { int result // times 只有两个参数,所以可以使用这种方式来写 ,具体的实现可以看源码,非常简单 number.times { num -> result += num } return result; }
字符串的结合使用
定义一个字符串:
String str = "the 2 and 3 is 5" 1 each 遍历 str.each { String temp -> print temp //the 2 and 3 is 5 } //看一下 each 方法的源码 public static <T> T each(T self, Closure closure) { //第一个是迭代器,第二个则是闭包了 each(InvokerHelper.asIterator(self), closure); return self; } public static <T> Iterator<T> each(Iterator<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure closure) { //遍历 字符串, while (self.hasNext()) { Object arg = self.next(); //调用闭包,传入了一个参数,从这里就可以知道我们在定义闭包的时候需要加一个参数 closure.call(arg); } return self; }
查找符合条件的第一个
println str.find { String s -> //返回 boolean 。是否符合条件,这里的条件为:是否是数字 s.isNumber() } //结果:2 ,第一个符合结果的是2,看一下源码 public static Object find(Object self, Closure closure) { //将闭包弄成了 boolean 类型的 BooleanClosureWrapper bcw = new BooleanClosureWrapper(closure); //迭代 for (Iterator iter = InvokerHelper.asIterator(self); iter.hasNext();) { Object value = iter.next(); //调用闭包,如果返回 true。则表示满足条件,接着就将 value 返回,然后就退出了。不在执行 if (bcw.call(value)) { return value; } } return null; } //查找全部 println str.findAll { String s -> return s.isNumber() } //结果:[2, 3, 5] ,查看源码可知找到后会存在集合中,最后进行返回
判断是否包含数字
println str.any { String s -> return s.isNumber() // true } //源码可自行查看
字符串是否每一项都为数字
println str.every { String s -> s.isNumber() //false } //源码 public static boolean every(Object self, Closure predicate) { return every(InvokerHelper.asIterator(self), predicate); } public static <T> boolean every(Iterator<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure predicate) { BooleanClosureWrapper bcw = new BooleanClosureWrapper(predicate); while (self.hasNext()) { //是否满足闭包中的条件 if (!bcw.call(self.next())) { return false; } } //循环完成后表示都满足条件,返回true return true; }
将字符串转为集合
println str.collect { //将 字符转换大写 it.toUpperCase() } //查看源码 public static <T> List<T> collect(Object self, Closure<T> transform) { //这里创建了一个新的集合 return (List<T>) collect(self, new ArrayList<T>(), transform); } public static <T> Collection<T> collect(Object self, Collection<T> collector, Closure<? extends T> transform) { //给字符串加上迭代器 return collect(InvokerHelper.asIterator(self), collector, transform); } public static <S,T> Collection<T> collect(Iterator<S> self, Collection<T> collector, @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends T> transform) { while (self.hasNext()) { //调用闭包中的方法,将返回的结果保存到集合中 collector.add(transform.call(self.next())); } //返回集合 return collector; }