前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >11. Groovy 运算符-区间运算符,下标运算符,钻石运算符等学习

11. Groovy 运算符-区间运算符,下标运算符,钻石运算符等学习

作者头像
zinyan.com
发布2022-12-07 18:28:55
7280
发布2022-12-07 18:28:55
举报
文章被收录于专栏:zinyanzinyan

1.介绍

Groovy学习的第11篇内容。继续分享关于运算符的知识。本篇将会分享比较多的几种运算符的使用,主要为:区间运算符..,三路比较运算符(别称宇宙飞船运算符,<=>),下标运算符[],索引安全运算符?[],成员运算符(关键字in),恒等运算符==,强制运算符as,钻石运算符<>和调用运算符()

我的所有示例代码。都可以直接在VS 编译器中直接运行。需要安装有:Groovy插件和Code Runner 插件。(本地环境配置了Groovy SDK地址,Java SDK 地址)

2. 区间运算符-Range operator

Groovy支持范围的概念,并提供了一个符号:..来创建对象范围。而针对这个范围,通常使用区间来进行定义。

在现在比较流行的高级语言中,都有对区间的支持。只是有些将这个定义为语法特性,在Groovy文档中,将区间定义放在了运算符的介绍目录中了。

具体示例如下:

代码语言:javascript
复制
def range = 1..10  //创建了一个1到10的区间对象。
println(range) //直接打印 输出:1..10
println(range.collect()) //输出[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
println(range.size()) //输出10 
assert (range) instanceof List  //能够通过断言检测

同上面的示例就可以看到了。区间定义的实际上是一个继承List的对象。是一个闭区间

在Groovy中,区间对象为:groovy.lang.Range它继承了List接口。

同时创建区间时也可以创建开区间。通过<符号。示例如下:

代码语言:javascript
复制
def range = 1..5 //创建1到5的区间
println(range.collect()) //输出 [1,2,3,4,5]
range =1<..5     //创建大于1等于5的区间
println(range.collect()) //输出 [2,3,4,5]
range =1<..<5    //创建大于1小于5的区间
println(range.collect()) //输出 [2,3,4]

区间的实现是轻量级的,可以从任何具有next()previous()方法的Comparable对象创建一个区间。也就是说不止int可以创建区间。

例如字符串区间:

代码语言:javascript
复制
def range ='a'..'d'
println(range.collect()) //输出 [a, b, c, d]
range ='a'<..'d'  
println(range.collect()) //输出 [b, c, d]
range ='a'<..<'d'  
println(range.collect()) //输出 [b, c]

3. 三路比较运算符-Spaceship operator

三路比较运算符(别称宇宙飞船运算符),它的命名和它的符号有很大关系,标识符为:<=>。具体实现示例如下:

代码语言:javascript
复制
def x =1
def y =2
println( x <=> y)  //输出结果为-1

因为它的比较运算符实际上是实现了compareTo的比较值输出。

CompartTo的比较关系中。

  • 左右两边相等:返回0。
  • 左边小于右边:返回-1。
  • 左边大于后边:返回1。

我们可以通过三路比较运算符简写compareTo的比较运算而已。所以,三路比较运算符输出的值永远都只会有-1,0,1这三种情况。

让我们通过示例加深一下印象,示例如下:

代码语言:javascript
复制
//整数的比较
println(1<=>2) //输出-1 。因为左边小于右边
println(2<=>1) //输出1 ,因为左边大于右边
println(2<=>2) //输出0 ,因为左右两边相等
//字符串的比较
println('zin'<=>'yan') //输出 1 因为左边字符串转code后比右边大
println('a'<=>'b')// 输出-1, 因为a转code后比b要小。

4. 下标运算符-Subscript operator

下标运算符是getAtputAt方法的缩写。我们使用List获取参数时,使用的[int]就是下标运算符了。

示例代码如下:

代码语言:javascript
复制
def list=['zin','yan','z同学'] //创建一个字符串List
println(list.getAt(1)) //输出 yan
println(list[1]) //输出也是yan,  这种就叫做下标运算符

我们直接通过下标运算符省略了get写法而已。在上面的场景下下标运算符就是getAt的简写。

代码语言:javascript
复制
def list=['zin','yan','z同学'] //创建一个字符串List
list.putAt(2,'com')  //例如通过putAt 将下标为2的元素进行修改
println(list.getAt(2))  //通过getAt获取的值。输出为:com

而我们通过下标运算符缩写putAt就可以写为:

代码语言:javascript
复制
def list=['zin','yan','z同学'] 
list[2]='com'  
println(list[2])  //通过getAt获取的值。输出为:com

这也是官方文档中介绍的,下标运算符是是getAt 还是putAt 得根据该赋值操作是在等号的左边还是右边来决定的。

如果是在右边,那么就是getAt,如果是在左边那么就是putAt了。

PS:Java中集合对象是没有这个写法的。所以Groovy文档中才会专门介绍了下标运算符。

5. 索引安全运算符-Safe index operator

在Groovy 3.0开始,引入了索引安全运算符?[] 它的作用和?.是类似的。主要也是用来避免Null值造成的程序异常。

?.是在引用对象时进行Null过滤,?[]就是在下标运算符使用时判断集合或者数组对象是否为Null。(ps:不是判断里面的item是否为Null哦)

PS:Groovy分的很细啊,这些运算符之类的信息。

具体示例如下所示:

代码语言:javascript
复制
String[] array = null  //创建一个空数组
//println(array[1]) //这个写法会提示Null值异常,NullPointerException错误
println(array?[1]) //这个写法会输出 null

def list=null
println(list[2]) //会提示NullPointerException错误
println(list?[2]) //会输出null

6. 成员运算符-Membership operator

成员运算符,也叫做隶属运算符。使用关键字:in来表现。在普通对象中它相当于调用isCase方法。在List中它相当于调用contains方法。

示例如下:

代码语言:javascript
复制
def list = ['zin','yan','Z同学']
def s = 'zin' in list // 
println(s)  //输出:true
def x = 'com' !in list  
println(x)  //输出 :true     
//上面的示例等效于下面的:
println(list.contains('zin'))  //输出 true
println(!list.contains('com'))  //输出true

结合示例,我们就能比较清晰的弄明白in关键字的作用了。它就是用来检测List等集合对象中是否包括。如果包括就返回true,不包括返回false

7. 恒等运算符-Identity operator

恒等运算符也叫做恒等算式。使用的标识符为:==。在Groovy中,使用==测试相等性不同于在Java中使用相同的运算符。在Groovy中,它调用equals。如果要比较引用相等性,应使用is进行比较。示例如下:

代码语言:javascript
复制
def list1 = ['zinyan','z同学']        
def list2 = ['zinyan','z同学']     
println(list1 == list2)      //输出 true
println(list1.is(list2))    //输出 false 比较两个对象的引用
println(list1 !== list2)     //输出 true

!==运算符在第六篇https://zinyan.com/?p=394 关系运算符中有过介绍。

在这里再次复习一遍,它比较的是两个对象的引用。同时必须是Groovy 3.0.0版本才能使用。老版本建议使用is进行比较吧。

在Groovy中 的is运算符才等同于java中的== 比较符。这中间是有差异的

8. 强制运算符-Coercion operator

在Groovy中使用as表示强制转换。强制将对象从一种类型转换为另一种类型,但它们与赋值不兼容。在Java中的强制转换通常是写作:

代码语言:javascript
复制
Yan x =new Yan();
Zinyan z =(Zinyan) x;

上面如果两者之间如果不能正确转换的话,我们在开发过程中不知道。只有运行状态才会报错ClassCastException

为了避免这个错误。Groovy通过 as关键字实现强制转换:

代码语言:javascript
复制
Integer x= 123
String s = x as String
println(s) //输出123 
//我们如果将S 强制转换为int 
x = s as Integer
println(x) //输出123

在上面的示例中,两个参数能够正确互相转换。

当一个对象被强制转换为另一个对象时,除非目标类型与源类型相同,否则强制将返回一个新对象。

强制规则因源和目标类型而异,如果找不到转换规则,强制可能会失败。例如:

代码语言:javascript
复制
String s ="zinyan.com"
//我们如果将S 强制转换为int 
Integer y = s as Integer
println(y)

就会提示错误:Caught: java.lang.NumberFormatException: For input string: "zinyan.com"

这是因为强制转换时找不到规则了。但是其实强制转换是调用了类的asType方法。我们可以通过重构该方法,实现自定义转换规则。

as强制转换的逻辑按照我们定义的规则进行转换。

示例代码如下:

代码语言:javascript
复制
//自定义类 
class Identifiable {
    String name
}
//自定义类
class User {
    Long id
    String name

    //重构asType方法
    def asType(Class target) {                                              
        if (target == Identifiable) { //如果要转换的类是Identifiable类
            return new Identifiable(name: name)  //那么就将它的name值进行复制即可
        }//否则返回 转换失败异常
        throw new ClassCastException("User cannot be coerced into $target")
    }
}

def u = new User(name: 'zinyan')                                            
def p = u as Identifiable    
println(p.name)       //输出:zinyan

转换过程中,其实就是创建了一个新的对象并进行赋值。这种可以优化很多样板代码。

9. 钻石运算符-Diamond operator

钻石运算符<>是一个语法上的纯糖运算符,用于支持与Java 7中同名运算符的兼容性。它用于指示泛型类型应该从声明中推断出来:

代码语言:javascript
复制
List<String> strings = new LinkedList<>()

在动态Groovy中,这是完全未使用的。在静态类型检查的Groovy中,它也是可选的,因为无论是否存在该运算符,Groovy type checker都会执行类型推断。

PS:所以这个就是java提供的一种纯糖运算符。Groovy中可以写,也可以不写。

10. 调用运算符-Call operator

调用运算符 () 就是为了隐式调用名为call的方法。只要实现了call方法的对象,都可以直接使用()进行调用。

示例代码如下:

代码语言:javascript
复制
//创建一个类
class MyCallable {
    //自定义一个call方法
    int call(int x) {           
        2*x
    }
}

def mc = new MyCallable()
println(mc.call(202)) //返回:404
println(mc(202)) //返回:404

通过示例代码就可以看出来了mc()mc.call()是等效的。

11. 小结

通过本篇的学习,对于Groovy中的很多语法有了更多的理解。因为上面的这些语法,在实际Groovy脚本的使用中非常频繁。

当我们弄明白每个语法的含义时,我们写Groovy时就会更简单,清晰,明了。

本篇内容参考于Groovy官方文档:http://docs.groovy-lang.org/docs/groovy-4.0.6/html/documentation/#_range_operator。

下一篇介绍各种运算符的优先级知识点

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-11-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 zinyan 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.介绍
  • 2. 区间运算符-Range operator
  • 3. 三路比较运算符-Spaceship operator
  • 4. 下标运算符-Subscript operator
  • 5. 索引安全运算符-Safe index operator
  • 6. 成员运算符-Membership operator
  • 7. 恒等运算符-Identity operator
  • 8. 强制运算符-Coercion operator
  • 9. 钻石运算符-Diamond operator
  • 10. 调用运算符-Call operator
  • 11. 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档