1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Groovy之操作符

        共 8084字,需瀏覽 17分鐘

         ·

        2022-05-15 02:29

        這里對(duì)Groovy中常見的操作符進(jìn)行介紹

        abstract.png

        操作符用法

        算術(shù)操作符

        同Java一樣,在算術(shù)操作符方面Groovy并無二致。示例代碼如下所示

        class?OperatorDemo?{????
        ????static?void?arithmetic()?{
        ????????//?加
        ????????assert?3+4?==?7
        ????????//?加并賦值
        ????????def?foo1?=?3
        ????????foo1?+=?4
        ????????assert?foo1?==?7

        ????????//?減
        ????????assert?4-3?==?1
        ????????//?減并賦值
        ????????def?foo2?=?4
        ????????foo2?-=?3
        ????????assert?foo2?==?1

        ????????//?乘
        ????????assert?4*3?==?12
        ????????//?乘并賦值
        ????????def?foo3?=?4
        ????????foo3?*=3
        ????????assert?foo3?==?12

        ????????//?除
        ????????assert?12/3?==?4
        ????????//?除并賦值
        ????????def?foo4?=?12
        ????????foo4?/=?3
        ????????assert?foo4?==4

        ????????//?求余
        ????????assert?13%3?==?1
        ????????//?求余并賦值
        ????????def?foo5?=?13
        ????????foo5?%=?3
        ????????assert?foo5?==?1

        ????????//?冪
        ????????assert?2**3?==?8
        ????????//?冪并賦值
        ????????def?foo6?=?2
        ????????foo6?**=?3
        ????????assert?foo6?==?8

        ????????//?一元運(yùn)算符?+?表示?正數(shù)
        ????????assert?+3?==?3
        ????????//?一元運(yùn)算符?-?表示?負(fù)數(shù)
        ????????assert?-4?==?0-4
        ????????assert?-(-11)??==?11

        ????????//?后綴自增
        ????????def?a1?=?2
        ????????def?b1?=?a1++
        ????????assert?a1?==?3
        ????????assert?b1?==?2

        ????????//?前綴自增
        ????????def?a2?=?2
        ????????def?b2?=?++a2
        ????????assert?a2?==?3
        ????????assert?b2?==?3

        ????????//?后綴自減
        ????????def?a3?=?2
        ????????def?b3?=?a3--
        ????????assert?a3?==?1
        ????????assert?b3?==?2

        ????????//?前綴自減
        ????????def?a4?=?2
        ????????def?b4?=?--a4
        ????????assert?a4?==?1
        ????????assert?b4?==?1
        ????}
        }???

        關(guān)系運(yùn)算符

        Groovy的關(guān)系運(yùn)算符示例如下所示

        class?OperatorDemo?{????
        ????static?void?relational()?{
        ????????//?相等
        ????????assert?(3*4)?==?(10+2)

        ????????//?不相等
        ????????assert?3?!=?4

        ????????//?小于
        ????????assert?3?4

        ????????//?小于等于
        ????????assert?3<=4
        ????????assert?4<=4

        ????????//?大于
        ????????assert?5?>?4
        ????????
        ????????//?大于等于
        ????????assert?5>=4
        ????????assert?5>=5
        ????}
        }

        邏輯運(yùn)算符

        Groovy在邏輯運(yùn)算符支持常見的與、或、非,同時(shí)具備短路求值的特點(diǎn)

        class?OperatorDemo?{????
        ????static?void?logical()?{
        ????????//?邏輯與,?支持短路求值
        ????????assert?true?&&?true
        ????????
        ????????//?邏輯或,?支持短路求值
        ????????assert?false?||?true
        ????????
        ????????//?邏輯非
        ????????assert?!false
        ????}
        }

        位運(yùn)算

        Groovy與Java一樣,同樣支持位運(yùn)算。示例如下所示

        class?OperatorDemo?{
        ????static?void?bit()?{
        ????????//?按位與
        ????????int?a?=?0b1010??//?a?=?10
        ????????assert?a?==?10
        ????????int?b?=?0b0110??//?b?=?6
        ????????assert?b?==?6
        ????????int?c?=?0b0010??//?c?=?2
        ????????assert?c?==2
        ????????assert?(a&b)?==?c

        ????????//?按位或
        ????????int?d?=?0b1110??//?d?=?14
        ????????assert?d?==?14
        ????????assert?(a|b)?==?d

        ????????//?按位異或
        ????????int?e?=?0b1100
        ????????assert?e?==?12
        ????????assert?(a^b)?==?e

        ????????//?按位取反
        ????????byte?f?=?0b00001111
        ????????assert?f?==?15
        ????????byte?h?=?0b11110000
        ????????assert?h?==?-16
        ????????assert?(~f)?==?h

        ????????//?左移
        ????????byte?i?=?0b00000011
        ????????assert?i?==?3
        ????????byte?j?=?0b00001100
        ????????assert?j?==?12
        ????????assert?(i<<2)?==?j

        ????????//?右移
        ????????assert?(j>>2)?==?i
        ????????//?右移:?左邊使用原符號(hào)位進(jìn)行填充,?右邊超出部分直接丟棄
        ????????byte?k?=?0b11111011
        ????????assert?k?==?-5
        ????????byte?p?=?0b11111110
        ????????assert?p?==?-2
        ????????assert?(k>>2)?==?p

        ????????//?無符號(hào)右移:?左邊使用0進(jìn)行填充,?右邊超出部分直接丟棄
        ????????int?q?=?0x8022_11ff?//?數(shù)字支持使用下劃線進(jìn)行劃分,?便于人眼查看
        ????????assert?q?==?-2145250817
        ????????int?r?=?0x0080_2211
        ????????assert?r?==?8397329
        ????????assert?(q>>>8)?==?r
        ????}
        }

        條件運(yùn)算符

        Groovy不僅提供了傳統(tǒng)的三元運(yùn)算符。還特別提供了Elvis運(yùn)算符、Elvis賦值運(yùn)算符。對(duì)于前者而言,如果Elvis運(yùn)算符左邊的操作數(shù)判定為真,則返回左邊操作數(shù); 否則返回右邊的操作數(shù);對(duì)于后者而言,Elvis賦值運(yùn)算符, 其是對(duì)Elvis運(yùn)算符的進(jìn)一步簡(jiǎn)化, 省去了再次賦值操作。示例如下所示

        class?OperatorDemo?{
        ????static?void?conditional()?{
        ????????//?三元運(yùn)算符
        ????????def?a1?=?(2>1)???3?:?4
        ????????assert?a1?==?3
        ????????def?a2?=?(2>3)???3?:?4
        ????????assert?a2?==?4

        ????????//?Elvis?運(yùn)算符,?如果?:運(yùn)算符左邊的操作數(shù)判定為真,則返回左邊操作數(shù);?否則返回右邊的操作數(shù)
        ????????//?可以視為簡(jiǎn)版的三元運(yùn)算符
        ????????def?b1?=?"Hello?World"
        ????????//??等同于?b1?=?(b1!=null?||?b1!="")???b1?:?"Hi"
        ????????b1?=?b1??:?"Hi"?//?非空字符串視為真
        ????????assert?b1?==?"Hello?World"
        ????????//?Elvis?運(yùn)算符
        ????????def?b2?=?""
        ????????b2?=?b2??:?"Hi"
        ????????assert?b2?==?"Hi"

        ????????//?Elvis賦值?運(yùn)算符,?其是對(duì)Elvis運(yùn)算符的進(jìn)一步簡(jiǎn)化,?省去了再次賦值操作
        ????????def?c1?=?"Hello?World"
        ????????c1??=?"Hi"
        ????????assert?c1?==?"Hello?World"

        ????????def?c2?=?""
        ????????c2??=?"Hi"
        ????????assert?c2?==?"Hi"
        ????}
        }

        正則操作符

        特別地,Groovy針對(duì)正則操作提供了相應(yīng)的操作符。示例如下所示

        class?OperatorDemo?{
        ????static?void?regular()?{
        ????????String?regex?=?/\S+\s+\S+/
        ????????//?模式操作符?~
        ????????def?pattern1?=?~regex
        ????????assert?pattern1?instanceof?Pattern
        ????????def?text1?=?"One?Two?Three?Four?Five"
        ????????def?matcher1?=?pattern1.matcher(text1)
        ????????assert?matcher1?instanceof?Matcher
        ????????assert?matcher1.size()?==?2
        ????????assert?matcher1[0]?==?"One?Two"
        ????????assert?matcher1[1]?==?"Three?Four"

        ????????//?查找運(yùn)算符?=~
        ????????//?具體地,其會(huì)在文本text1上應(yīng)用正則表達(dá)式regex,?生成matcher
        ????????def?matcher2?=?(text1?=~?regex)
        ????????assert?matcher2?instanceof?Matcher
        ????????assert?matcher2.size()?==?2
        ????????assert?matcher2[0]?==?"One?Two"
        ????????assert?matcher2[1]?==?"Three?Four"

        ????????//?匹配運(yùn)算符?==~,?其是完整的匹配,?而非部分匹配
        ????????boolean?b1?=?"One?Two?Three?Four"?==~?regex
        ????????boolean?b2?=?"One?Two"?==~?regex
        ????????assert?b1?==?false
        ????????assert?b2?==?true
        ????}
        }

        對(duì)象操作符

        Groovy對(duì)于對(duì)象引用提供了豐富的操作符。需要特別提醒的是,在Java中對(duì)兩個(gè)對(duì)象引用使用==操作符比較的是兩個(gè)對(duì)象的地址是否一樣;而在Groovy中==操作符用于比較兩個(gè)對(duì)象的內(nèi)容是否一樣,事實(shí)上該操作符是通過equals方法實(shí)現(xiàn)的。當(dāng)然Groovy自然也是支持比較兩個(gè)對(duì)象的地址,其提供了===操作符。事實(shí)上該操作符是通過is方法實(shí)現(xiàn)的。示例代碼如下所示

        class?OperatorDemo?{?
        ????static?void?object()?{
        ????????def?person1?=?new?Person("remark":?"領(lǐng)軍人才")
        ????????//?通過.操作符訪問字段
        ????????person1.name?=?"Aaron"
        ????????assert?person1.name?==?"Aaron"
        ????????//?通過.操作符修改字段實(shí)際上是隱式調(diào)用setter方法
        ????????person1.age?=?18
        ????????assert?person1.age?==?218
        ????????//?通過.操作符獲取字段實(shí)際上是隱式調(diào)用getter方法
        ????????assert?person1.remark?==?":?領(lǐng)軍人才"

        ????????//?通過.@運(yùn)算符可以實(shí)現(xiàn)直接訪問字段,?而不是通過隱式調(diào)用getter、setter方法實(shí)現(xiàn)
        ????????assert?person1.@remark?==?"領(lǐng)軍人才"
        ????????person1.@age?=?17
        ????????assert?person1.age?==?17

        ????????//?安全引用操作符
        ????????Person?person2?=?null
        ????????//?如果?.安全引用操作符的引用為null,?則不會(huì)調(diào)用方法,?而是直接返回null以避免NPE
        ????????assert?person2?.getAge()?==?null
        ????????assert?person1?.getAge()?==?17

        ????????//?方法指針運(yùn)算符
        ????????MethodClosure?fun1?=?person1.&getAge
        ????????//?方法指針的類型是閉包
        ????????assert?fun1?instanceof?Closure
        ????????assert?fun1()?
        ==?17
        ????????assert?fun1.call()?==?17

        ????????//?方法指針同樣支持多分派
        ????????def?fun3?=?person1.&test1
        ????????assert?fun3.call("Bye")?==?"Aaron:?Bye"
        ????????assert?fun3.call(3)?==?"<17?+?3>?-->>?20"

        ????????//?可通過new獲取構(gòu)造器的方法指針
        ????????def?fun4?=?Person.&new
        ????????Person?person3?=?fun4.call("name":"Bob")
        ????????assert?person3.name?==?"Bob"

        ????????//?通過類先獲取非靜態(tài)方法的方法指針
        ????????def?fun2?=?String.&toUpperCase
        ????????//?在執(zhí)行閉包時(shí),?再傳入該類的實(shí)例,?以作為方法的調(diào)用者
        ????????assert?fun2.call("Hello")?==?"HELLO"
        ????????def?fun5?=?Person.&test1
        ????????assert?fun5.call(?person1,?"welcome"?)?==?"Aaron:?welcome"

        ????????//?方法指針運(yùn)算符同樣適用于靜態(tài)方法
        ????????def?fun6?=?String.&valueOf
        ????????assert?fun6.call(?false?)?==?"false"
        ????????assert?fun6.call(?996?)?==?"996"

        ????????//?Groovy對(duì)Java?8的::方法引用運(yùn)算符保持支持兼容
        ????????def?list1?=?["71","2","4"].stream()
        ????????????.map(?Integer::valueOf?)
        ????????????.collect(?Collectors.toList()?)
        ????????assert?list1?==?[71,2,4]

        ????????//?list1a,?list1b?引用地址相同
        ????????def?list1a?=?[1,2]?as?LinkedList
        ????????def?list1b?=?list1a
        ????????//?另外一個(gè)包含相同元素的列表
        ????????def?list2?=?[1,2]?as?LinkedList

        ????????//?判斷兩個(gè)引用的內(nèi)容是否相同
        ????????//?==?運(yùn)算符所對(duì)應(yīng)的方法是equals
        ????????assert?list1a?==?list2
        ????????assert?list1a.equals(?list2?)

        ????????//?類似地,?!=運(yùn)算符是對(duì)equals方法的結(jié)果進(jìn)行否定
        ????????assert?list1a?!=?[985,211]
        ????????assert?!(?list1a.equals([985,211])?)

        ????????//?判斷兩個(gè)引用的地址是否相同
        ????????//?===運(yùn)算符對(duì)應(yīng)is方法
        ????????assert?list1a?===?list1a
        ????????assert?list1a.is(list1b)
        ????????//?判斷兩個(gè)對(duì)象的引用地址是否不同
        ????????//?類似地,?!==運(yùn)算符是對(duì)is方法的結(jié)果進(jìn)行否定
        ????????assert?list1a?!==?list2
        ????????assert?!(?list1a.is(list2)?)
        ????}
        }

        class?Person?{
        ????String?name
        ????Integer?age
        ????String?remark

        ????void?setAge(Integer?age)?
        {
        ????????this.age?=?200?+?age
        ????}

        ????String?getRemark()?{
        ????????return?":?$remark"
        ????}

        ????/**
        ?????*?實(shí)現(xiàn)equals方法,?實(shí)現(xiàn)重載==運(yùn)算符
        ?????*?@param?other
        ?????*?@return
        ?????*/

        ????@Override
        ????boolean?equals(Object?other)?{
        ????????if?(!other
        ????????????||?!(other?instanceof?Person)
        ????????????||?name?!=?other.name
        ????????????||?age?!=?other.age
        ????????????||?remark?!=?other.remark?)?{
        ????????????return??false
        ????????}
        ????????return?true
        ????}

        ????String?test1(String?msg)?{
        ????????return?"$name:?$msg"
        ????}

        ????String?test1(Integer?num)?{
        ????????return?"<${this.age}?+?${num}>?-->>?${this.age+num}"
        ????}
        }

        其它

        Groovy中其它部分常見的操作符,示例如下所示

        class?OperatorDemo?{
        ????static?void?other()?{
        ????????//?飛船運(yùn)算符,?通過調(diào)用Comparable接口的compareTo方法進(jìn)行比較
        ????????//?15==15
        ????????assert?(15?<=>?15)?==?0
        ????????//?44>22
        ????????assert?(44?<=>?22)?==?1
        ????????//?22<44
        ????????assert?(22?<=>?44)?==?-1

        ????????//?安全索引運(yùn)算符?[],?作用類似于?.安全引用操作符
        ????????//?避免由于數(shù)組為null而導(dǎo)致的NPE
        ????????String[]?array1?=?["Amy",?"Aaron"]
        ????????array1?[1]?=?"Bob"
        ????????assert?array1?[0]?==?"Amy"
        ????????assert?array1?[1]?==?"Bob"
        ????????array1?=?null
        ????????//?array1為null,?將不會(huì)應(yīng)用索而是直接返回null
        ????????assert?array1?[0]?==?null

        ????????//?安全索引運(yùn)算符同樣適用于Map
        ????????def?map1?=?[:]
        ????????map1?["Aaron"]?=?18
        ????????assert?map1?["Aaron"]?==?18
        ????????map1?=?null
        ????????assert?map1?["Aaron"]?==?null

        ????????//?成員操作符
        ????????def?list1?=?["MicroSoft",?"Apple",?"Xiaomi",?"FaceBook"]
        ????????//?判定Apple是否是list1的成員
        ????????assert?"Apple"?in?list1
        ????????//?等效于調(diào)用isCase方法
        ????????assert?list1.isCase(?"Apple"?)
        ????????assert?!("Huawei"?in?list1)

        ????????assert?996?in?Integer
        ????????//?等效于調(diào)用isCase方法
        ????????assert?Integer.isCase(996)
        ????????assert?!(3.14f?in?Integer)

        ????????assert?3.14f?in?Float
        ????????assert?Float.isCase(?3.1f?)
        ????}
        }

        操作符重載

        在Groovy中,部分操作符是有對(duì)應(yīng)的方法。換言之,通過操作符或方法調(diào)用在本質(zhì)上效果是一致的。但操作符一旦有對(duì)應(yīng)的方法,就為我們提供了另外一種編程方式,即進(jìn)行操作符的重載。在特殊場(chǎng)景下,操作符的重載可以大大方便我們的使用。比如期望通過乘法符號(hào)計(jì)算兩個(gè)矩陣的乘積,在Java中這顯然是不可能。因?yàn)槲覀儾荒茏远x乘法操作符的具體邏輯,而在Groovy中則可以在我們自定義的矩陣類中通過重載乘法操作符實(shí)現(xiàn)。這里給出Groovy可以進(jìn)行重載的操作符及對(duì)應(yīng)的方法名

        figure 1.jpeg

        下面給出一個(gè)進(jìn)行重載操作符的示例,方便理解、使用

        class?OperatorOverLoad?{
        ????static?void?main(String[]?args){
        ????????testPlus()
        ????????testNext()
        ????????testCall()
        ????}
        ????
        ????static?void?testNext()?{
        ????????Food?food1?=?new?Food("西瓜",?14)
        ????????food1++
        ????????assert?food1.toString()?==?"Food?{?type=西瓜,?num=15?}"

        ????????def?food2?=?new?Food(type:?"哈蜜瓜"?)
        ????????food2++
        ????????assert?food2.toString()?==?"Food?{?type=哈蜜瓜,?num=1?}"
        ????}

        ????static?void?testPlus()?{
        ????????Food?food1?=?new?Food("橘子",?1)
        ????????Food?food2?=?new?Food("橘子",?2)
        ????????Food?food3?=?new?Food("type":?"橘子")
        ????????Food?food4?=?new?Food("type":?"蘋果")

        ????????assert?(food1?+?food2).toString()?==?"Food?{?type=橘子,?num=3?}"
        ????????assert?(food2?+?food3).toString()?==?"Food?{?type=橘子,?num=2?}"
        ????????assert?(food1?+?food4)?==?null
        ????}

        ????static?void?testCall()?{
        ????????Food?food1?=?new?Food("檸檬",?21)
        ????????def?str?=?food1()
        ????????//?顯式調(diào)用call方法
        ????????assert?food1.call()?==?"Food?{?type=檸檬,?num=21?}"
        ????????//?通過?調(diào)用運(yùn)算符()?調(diào)用?call方法
        ????????assert?food1()?==?"Food?{?type=檸檬,?num=21?}"
        ????}
        }

        class?Food?{
        ????String?type
        ????Integer?num

        ????Food(String?type,?Integer?num)?{
        ????????this.type?=?type
        ????????this.num?=?num
        ????}

        ????Food()?{
        ????}

        ????/**
        ?????*?重載加法運(yùn)算符+
        ?????*?@param?other
        ?????*?@return
        ?????*/

        ????Food?plus(Food?other)?{
        ????????if(?!this.type?||?this.type?!=?other?.type?)?{
        ????????????return?null
        ????????}

        ????????Integer?num1?=?this.num??:?0
        ????????Integer?num2?=?other.num??:?0
        ????????Integer?result?=?num1?+?num2
        ????????return?new?Food("type":type,?"num":?result)
        ????}

        ????/**
        ?????*?重載自增運(yùn)算符++
        ?????*?@return
        ?????*/

        ????Food?next()?{
        ????????this.num??=?0
        ????????this.num++
        ????????return?this
        ????}

        ????/**
        ?????*?重載調(diào)用運(yùn)算符()
        ?????*?@return
        ?????*/
        ????String?call()?{
        ????????return?toString()
        ????}

        ????@Override
        ????String?toString()?{
        ????????return?"Food?{?type=$type,?num=$num?}"
        ????}
        }

        參考文獻(xiàn)

        1. Groovy In Action · 2nd Edition ? Dierk K?nig、Guillaume Laforge著
        瀏覽 30
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产一级婬片久久久片A级 | 国产精品久久久久久久久久久免费看 | 亚洲成人一区 | 国模yumi私拍大尺度写真 | 久热色 | 黄色一级大片在线免费看国产 | 2021色欲 | 色综合五月天 | free×性护士vidos中国 | 欧美成人777奇米影视91色 |