groovy操作符

目录

数学运算符

对象运算符

空对象安全引用运算符

直接字段访问操作符 

方法指针操作符

 正则表达式运算符

其他操作符

扩展操作符

解包方法参数、列表元素、键值对

范围操作符

比较操作符

索引操作符

成员操作符

== 和is操作符

类型转换操作符

钻石操作符

调用操作符

操作符优先级表

操作符重载



数学运算符

#乘方
assert  2 ** 3 == 8

#非运算
assert (!true)    == false                      
assert (!'foo')   == false                      
assert (!'')      == true 

#三元表达式
result = (string!=null && string.length()>0) ? 'Found' : 'Not found'
result = string ? 'Found' : 'Not found'

#艾维斯运算符
displayName = user.name ? user.name : 'Anonymous' 
#进一步简写为:  
displayName = user.name ?: 'Anonymous'       

对象运算符

空对象安全引用运算符

避免抛出NullPointerException 这个异常。

def person = Person.find { it.id == 123 }    
def name = person?.name                      
assert name == null   

直接字段访问操作符 

接字段访问 .@ 可以跳过 getXXX 方法,直接获得字段的值

assert user.@name == 'Bob'

方法指针操作符

方法指针 (.&) 操作符可以获取一个方法指针,后面再调用这个指针

def str = 'example of method reference'            
def fun = str.&toUpperCase                         
def upper = fun()  

方法指针获得的值是一个groovy.lang.Closure 类型,因此可以用到任何需要闭包的地方,非常适合策略模式

def transform(List elements, Closure action) {                    
    def result = []
    elements.each {
        result << action(it)
    }
    result
}
String describe(Person p) {                                       
    "$p.name is $p.age"
}
def action = this.&describe                                       
def list = [
    new Person(name: 'Bob',   age: 42),
    new Person(name: 'Julia', age: 35)]                           
assert transform(list, action) == ['Bob is 42', 'Julia is 35']    

Groovy 允许重载多个同名方法,如果方法指针指向重载同名方法,则根据参数类型来判断调用哪个方法

def doSomething(String str) { str.toUpperCase() }    
def doSomething(Integer x) { 2*x }                   
def reference = this.&doSomething                    
assert reference('foo') == 'FOO'                     
assert reference(123)   == 246   

 正则表达式运算符

模式运算符、匹配对象操作符、直接匹配操作符

略。

其他操作符

扩展操作符

扩展操作符的本质是迭代调用并生成列表,因此任何实现了 Iterable 接口的对象都可以使用扩展操作符

class Component {
    Long id
    String name
}

class CompositeObject implements Iterable<Component> {
    def components = [
        new Component(id: 1, name: 'Foo'),
        new Component(id: 2, name: 'Bar')]

    @Override
    Iterator<Component> iterator() {
        components.iterator()
    }
}

def composite = new CompositeObject()

assert composite*.id == [1,2]
assert composite*.name == ['Foo','Bar']

解包方法参数、列表元素、键值对

1.解包方法参数
下面这个方法需要三个参数
int function(int x, int y, int z) {
    x*y+z
}

下面这个列表有三个元素
def args = [4,5,6]

将列表解包为三个参数传给方法
assert function(*args) == 26

位置可以随意
args = [4]
assert function(*args,5,6) == 26

2.解包列表元素
def items = [4,5]                      
def list = [1,2,3,*items,6]            
assert list == [1,2,3,4,5,6]    

3.解包键值对
def m1 = [c:3, d:4]                   
def map = [a:1, b:2, *:m1]            
assert map == [a:1, b:2, c:3, d:4]    

如果出现重复的的键,后面的值将替换前面的值
def m1 = [c:3, d:4]                   
def map = [a:1, b:2, *:m1, d: 8]      
assert map == [a:1, b:2, c:3, d:8]

范围操作符

范围操作符 (..) 创建一个 groovy.lang.Range 对象,这个类型同时实现了 List 接口

def range = 0..5                                    
assert (0..5).collect() == [0, 1, 2, 3, 4, 5]       
assert (0..<5).collect() == [0, 1, 2, 3, 4]         
assert (0..5) instanceof List                       
assert (0..5).size() == 6              

Range 对象是轻量级的,仅仅存储了上下边界,因此要创建 Range 还必须实现 Comparable 接口中的 next() 方法和 previous() 方法。因为字符对象实现了这两个方法,因此可以向下面这样用

assert('a'..'d').collect()==['a','b','c','d']

比较操作符

比较操作符 (<=>) 其实就是 compareTo 方法

assert (1 <=> 1) == 0
assert (1 <=> 2) == -1
assert (2 <=> 1) == 1
assert ('a' <=> 'z') == -1

索引操作符

索引操作符本质上是调用 getAtputAt 方法,可以切片获取或者切片赋值

def list = [0,1,2,3,4]
assert list[2] == 2                         
list[2] = 4                                 
assert list[0..2] == [0,1,4]                
list[0..2] = [6,6,6]                        
assert list == [6,6,6,3,4]  

可以重写 getAt/putAt 方法,实现一些自定义的行为

class User {
    Long id
    String name
    def getAt(int i) {                                             
        switch (i) {
            case 0: return id
            case 1: return name
        }
        throw new IllegalArgumentException("No such element $i")
    }
    void putAt(int i, def value) {                                 
        switch (i) {
            case 0: id = value; return
            case 1: name = value; return
        }
        throw new IllegalArgumentException("No such element $i")
    }
}
def user = new User(id: 1, name: 'Alex')                           
assert user[0] == 1                                                
assert user[1] == 'Alex'                                           
user[1] = 'Bob'                                                    
assert user.name == 'Bob'        

成员操作符

成员操作符 (in) 相当于调用了列表的 contains 方法或者 isCase 方法

def list = ['Grace','Rob','Emmy']
assert ('Emmy' in list)  

calling list.contains('Emmy')list.isCase('Emmy')是同样的功能

== 和is操作符

在 Groovy 中, == 仅仅检测值是否相同,如果想检测是否是同一个对象,使用 is 操作符

def list1 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']        
def list2 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']        
assert list1 == list2                                       
assert !list1.is(list2)  

类型转换操作符

转型操作符 (as) 可以转换一些不兼容变量的类型,例如下面的转换会抛出异常
Integer x = 123
String s = (String) x  

用转型操作符可以正确转换
Integer x = 123
String s = x as String  

转型的本质实际上是调用了对象的 asType 方法,可以重写这个方法实现一些自定义的行为
class Identifiable {
    String name
}
class User {
    Long id
    String name
    def asType(Class target) {                                              
        if (target==Identifiable) {
            return new Identifiable(name: name)
        }
        throw new ClassCastException("User cannot be coerced into $target")
    }
}
def u = new User(name: 'Xavier')                                            
def p = u as Identifiable                                                   
assert p instanceof Identifiable                                            
assert !(p instanceof User)

钻石操作符

钻石操作符 (<>) 仅仅是为了兼容 Java 7 中的泛型,目前在 Groovy 中还没有什么用处。

List<String> strings = new LinkedList<>()

调用操作符

调用操作符 () 隐式调用 call 方法。可以重写 call 实现一些自定义的行为,然后用调用操作符调用

class MyCallable {
    int call(int x) {           
        2*x
    }
}

def mc = new MyCallable()
assert mc.call(2) == 4          
assert mc(2) == 4      

操作符优先级表

略。参见:http://groovy-lang.org/operators.html#Operator%20precedence

操作符重载

类似于c++的操作符重载,Groovy 中的大部分操作符都可以重新定义,例如:

class Bucket {
    int size

    Bucket(int size) { this.size = size }

    Bucket plus(Bucket other) {                     
        return new Bucket(this.size + other.size)
    }
}

#方法 plus() 重载了 + 操作符
def b1 = new Bucket(4)
def b2 = new Bucket(11)
assert (b1 + b2).size == 15  

下表是各个操作符的函数名称:

操作符方法操作符方法
+a.plus(b)a[b]a.getAt(b)
-a.minus(b)a[b] = ca.putAt(b, c)
*a.multiply(b)a in bb.isCase(a)
/a.div(b)<<a.leftShift(b)
%a.mod(b)>>a.rightShift(b)
**a.power(b)>>>a.rightShiftUnsigned(b)

|

a.or(b)

++

a.next()

&a.and(b)--a.previous()
^a.xor(b)+aa.positive()
asa.asType(b)-aa.negative()
a()a.call()~aa.bitwiseNegative()

笔记出处:https://www.jianshu.com/p/1339ab4f35dd

原文出处:http://groovy-lang.org/syntax.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值