Groovy运算符

一、运算符

算术运算符

        Groovy支持数学和其他编程语言中常见算术运算符,支持所有的Java运算符。

        普通算术运算符

        +:加法
        -:减法
        *:乘法
        /:除法
        %:取余
        **:幂

        一元运算符

        +和-还可以做为一元运算符。同时++、--还可以做为前缀或后缀来增加或减少值。

        赋值算术运算符

        将普通运算符与等号一起使用就可以做为赋值运算符,包括+=、-=、*=、/=、%=、**=。赋值运算符将符号两边变量和数字进行相应的运算后,赋值给符号左边的变量。

关系运算符

        关系运算符用于比较两个对象的大小。包括==、!=、<、<=、>、>=。

逻辑运算符

        Groovy提供了三种逻辑运算符:&&(与)、||(或)、!(非)。其中!优先级高于&&,&&优先级高于||。&&、||为短路运算符,即当||左边为true时,就会直接返回true,不会计算右边的真假。同理当&&左边为false时,就会直接返回false,不会计算右边的真假。

位运算符

        位运算符包括:&(与)、|(或)、^(异或)、~(取反)。位运算符可以用于byte或int类型,并返回int类型。在Groovy中,位运算符可以重载,所以可以为任何对象定义运算符的行为。

条件运算符

        取反运算符

        使用“!”来反转布尔表达式的值。取反操作可以与Groovy真值结合使用。

        三目运算符

        三目运算符“?   :”等价于一个if/else的赋值语句。三目运算符也可以与Groovy真值结合使用。

        Elvis运算符

        Elvis运算符“?:”是三目运算符的简写,如果表达式为真,则值为表达式的值,否则为运算符右边的值。使用Elvis运算符减少了代码冗余和重构时出现错误的风险。

对象运算符

        安全引用运算符

        安全引用运算符“?.”用来避免空指针异常,当通过对象的引用访问对象的方法或属性时,如果引用的对象为null,则返回null,不会抛出空指针异常。

        直接字段访问运算符

        Groovy中,“a.b”表示通过调用对象a的b属性的getter方法来获取b。如果想要直接访问属性b,需要使用直接字段访问运算符“.@”。

        方法指针运算符

        方法指针运算符“.&”通常用来在变量中保存方法的引用。方法引用的类型是groovy.lang.Closure,所以任何可以使用闭包的地方都可以使用。方法指针由接收者和方法名绑定的,参数会在运行时解析,所以对于多个同名、语法相同的方法,会在运行时根据参数的不同选择合适的方法。

正则表达式运算符

        模式运算符

        模式运算符“~”是一种简便的创建java.util.regex.Pattern实例的方法。通常与斜杠字符串或美元斜杠字符串一起使用,因为不需要对斜杠或者美元符号进行转义,同时也可以与Groovy中的任何类型的字符串一起使用。

        查找运算符

        查找运算符“=~”用来创建java.util.regex.Matcher实例。

        匹配运算符

        匹配运算符“==~”是查找运算符的一种变体,不返回Matcher实例,直接返回布尔类型实例。

其他运算符

        展开运算符

        展开运算符“*.”用于调用聚合对象中的所有项的一个动作,等价于调用每一个项的动作,并将结果存入列表中。当聚合对象中的项为null时,展开操作符会返回null,不会抛出空指针异常。还可以通过“*”+变量名的方式展开方法参数或者列表,通过“*:”+变量名的方式展开映射。展开操作符可以作用于任何实现了Iterable接口的对象。与展开列表不同的是,展开映射时,如果不会覆盖原本存在的键对应的值。

        范围运算符

        范围运算符“..”用于创建范围对象。可以对任意具有next/previous方法来确定在范围内其下一项/前一项的Comparable对象创建范围对象,范围对象实现了List接口。

        比较运算符

        间隔运算符“<=>”等价于compareTo方法,用于比较两个值的大小,如果左边大于右边返回1,如果左边小于右边返回-1,如果相等返回0。

        下标运算符

        下标运算符“[ ... ]”是getAt或putAt方法的简写,下表运算符与getAt/putAt方法的自定义实现是重构对象的简便方法。

        从属关系运算符

        从属关系运算符“in”等价于调用isCase方法,对于列表等价于调用contains方法。

       相等运算符

        相等元素符“==”与Java中不同,在Groovy中等价于equals方法,如果要判断引用是否相同,需要使用“is”。

        强转运算符

        强转运算符“()”是“as”的一种特殊变体,用于将一个对象转换成另一个对象,如果两个对象源类型不同会抛出类型转换异常。强制转换的规则取决于源和目标类型,如果没有找到转换规则就会转换失败,实现asType方法可以自定义转换规则。

        菱形运算符

        菱形运算符“<>”用于兼容java7中的同名运算符,用来表示应该从声明中推断出泛型类型。

        调用运算符

        调用运算符“()”用于隐式的调用call方法,对于任何定义call方法的对象,都可以忽略“.call”直接使用“()”。

二、优先级

        优先级又高到低分别为:
        1.分为六类:
            1)  new、()创建对象、明确的括号
            2)  ()、{}、[]方法调用、闭包、列表/映射字面量
            3)  .、.&、.@成员访问、方法闭包、字段访问
            4)  ?.、*、*.、*:安全引用、展开运算符、展开列表、展开映射
            5)  ~、!、(type)位取反、非、强制类型转换
            6)  []、++、--列表、映射、数组的索引、指针递增/减
        2.**幂运算
        3.++、--、+、-递增/减、一元加/减运算
        4.*、/、%乘法、除法、取余’
        5.+ -普通加/减法
        6.<<、>>、>>>、..、..<左/右位移、无符号右移、范围
        7.<、<=、> 、>=、in、instanceof 、as、比较运算符、in、对象类型判断、强制类型转换
        8.==、!=、<=>等于、不等于、比较运算符
        9.&位与
        10.^位异或
        11.|位或
        12.&&逻辑与
        13.||逻辑或
        14.? :、?:三目运算符、elvis运算符
        15.=、**=、*=、/=、%=、+=、-=、<<=、>>=、>>>=、&=、^=、|=赋值运算符

三、运算符重载

        Groovy中可以为自定义的类重载操作符,除了比较器之外所有的操作符都有对应的方法,重载的方法必须是public的,并且有正确的名字和参数数量。参数类型是操作符右边想要支持的类型。操作符及对应方法如下:
        +    a.plus(b)
        -     a.minus(b)
        *     a.multiply(b)
        /     a.div(b)
        %    a.mod(b)
        **    a.power(b)
        |      a.or(b)
        &    a.and(b)
        ^    a.xor(b)
        as    a.asType(b)
        a()    a.call()
        a[b]    a.getAt(b)
        a[b] = c    a.putAt(b, c)
        a in b    b.isCase(a)
        <<    a.leftShift(b)
        >>    a.rightShift(b)
        >>>    a.rightShiftUnsigned(b)
        ++    a.next()
        --    a.previous()
        +a    a.positive()
        -a    a.negative()
        ~a    a.bitwiseNegate()

四、简单示例

//普通算术运算符
assert  1  + 2 == 3
assert  4  - 3 == 1
assert  3  * 5 == 15
assert  3  / 2 == 1.5
assert 10  % 3 == 1
assert  2 ** 3 == 8
//一元运算符
assert +3 == 3
assert -4 == 0 - 4
assert -(-1) == 1

def a = 2
def b = a++ * 3             
assert a == 3 && b == 6

def c = 3
def d = c-- * 2             
assert c == 2 && d == 6

def e = 1
def f = ++e + 3             
assert e == 2 && f == 5

def g = 4
def h = --g + 1             
assert g == 3 && h == 4
//赋值运算符
def a = 4
a += 3
assert a == 7

def b = 5
b -= 3
assert b == 2

def c = 5
c *= 3
assert c == 15

def d = 10
d /= 2
assert d == 5

def e = 10
e %= 3
assert e == 1

def f = 3
f **= 2
assert f == 9
//关系运算符
assert 1 + 2 == 3
assert 3 != 4

assert -2 < 3
assert 2 <= 2
assert 3 <= 4

assert 5 > 1
assert 5 >= -2
//逻辑运算符
assert !false           
assert true && true     
assert true || false
//逻辑运算符-短路运算符
boolean checkIfCalled() {   
    called = true
}

called = false
true || checkIfCalled()
assert !called              

called = false
false || checkIfCalled()
assert called               

called = false
false && checkIfCalled()
assert !called              

called = false
true && checkIfCalled()
assert called
//位运算符
int a = 0b00101010
assert a == 42
int b = 0b00001000
assert b == 8
assert (a & a) == a                     
assert (a & b) == b                     
assert (a | a) == a                     
assert (a | b) == a                     

int mask = 0b11111111                   
assert ((a ^ a) & mask) == 0b00000000   
assert ((a ^ b) & mask) == 0b00100010   
assert ((~a) & mask)    == 0b11010101
//条件运算符
assert (!true)    == false                      
assert (!'foo')   == false                      
assert (!'')      == true  
//三目运算符
result = string ? 'Found' : 'Not found'
//elvis运算符
displayName = user.name ?: 'Anonymous' 
//安全引用运算符
def person = Person.find { it.id == 123 }    
def name = person?.name                      
assert name == null 
//直接字段访问运算符
class User {
    public final String name                 
    User(String name) { this.name = name}
    String getName() { "Name: $name" }       
}
def user = new User('Bob')
assert user.name == 'Name: Bob'

assert user.@name == 'Bob'  
//方法指针运算符
def str = 'example of method reference'            
def fun = str.&toUpperCase                         
def upper = fun()                                  
assert upper == str.toUpperCase()

def doSomething(String str) { str.toUpperCase() }    
def doSomething(Integer x) { 2*x }                   
def reference = this.&doSomething                    
assert reference('foo') == 'FOO'                     
assert reference(123)   == 246
//模式运算符
def p = ~/foo/
assert p instanceof Pattern

p = ~'foo'                                                        
p = ~"foo"                                                        
p = ~$/dollar/slashy $ string/$                                   
p = ~"${pattern}"      
//查找运算符
def text = "some text to match"
def m = text =~ /match/                                           
assert m instanceof Matcher                                       
if (!m) {//if (!m.find())                                                         
    throw new RuntimeException("Oops, text not found!")
}
//匹配运算符
m = text ==~ /match/                                              
assert m instanceof Boolean                                       
if (m) {//if (text ==~ /match/)                                                          
    throw new RuntimeException("Should not reach that point!")
}
//展开运算符
class Car {
    String make
    String model
}
def cars = [
   new Car(make: 'Peugeot', model: '508'),
   null,                                              
   new Car(make: 'Renault', model: 'Clio')]
assert cars*.make == ['Peugeot', null, 'Renault']     
assert null*.make == null


//展开方法参数
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
//展开列表
def items = [4,5]                      
def list = [1,2,3,*items,6]            
assert list == [1,2,3,4,5,6] 
//展开映射
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]

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]
//范围运算符
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 
assert ('a'..'d').collect() == ['a','b','c','d']
//比较运算符
assert (1 <=> 1) == 0
assert (1 <=> 2) == -1
assert (2 <=> 1) == 1
assert ('a' <=> 'z') == -1
//下标运算符
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]
//从属关系运算符
def list = ['Grace','Rob','Emmy']
assert ('Emmy' in list)
//相等运算符
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) 
//强制转换运算符
//ClassCastException
Integer x = 123
String s = (String) x
//success
Integer x = 123
String s = x as String
//菱形运算符
List strings = new LinkedList<>()
//调用运算符
class MyCallable {
    int call(int x) {           
        2*x
    }
}

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

你可能感兴趣的:(Groovy运算符)