Groovy運(yùn)算符

官方文檔

與Java一樣的就不展開了~

除號(hào)(/)的特殊行為

Groovy中的除/和Java的表現(xiàn)不一樣:

  • 當(dāng)兩個(gè)操作數(shù)中有一個(gè)是floatdouble時(shí)换帜,結(jié)果是double
  • 當(dāng)兩個(gè)操作數(shù)都是整型(short酿傍、char构韵、byte泉沾、intlongBigInteger)或者BigDecimal時(shí)箩兽,結(jié)果是BigDecimal
  • 如果要像Java那樣取整薇溃,需要調(diào)用intdiv方法
def result = 1 / 3.0f // 當(dāng)其中有一個(gè)是float或double時(shí)
println result.class  // 結(jié)果是:class java.lang.Double
println result        // 0.3333333333333333
println 4.intdiv(3)   // 結(jié)果為1,與Java一樣

def newResult = 1 / 2   // 當(dāng)兩個(gè)操作數(shù)都是整型
println newResult.class // class java.math.BigDecimal
println newResult       // 結(jié)果是0.5

指數(shù)運(yùn)算符(Power operator)

Groovy中引入了指數(shù)運(yùn)算符**。如2 ** 3表示為2的三次方梅肤。

// base and exponent are ints and the result can be represented by an Integer
// 基數(shù)和指數(shù)都是int,所得結(jié)果可以用int表示司蔬,那么結(jié)果就是int類型
assert 2**3 instanceof Integer    //  8
assert 10**9 instanceof Integer   //  1_000_000_000

// the base is a long, so fit the result in a Long
// (although it could have fit in an Integer)
// 基數(shù)是long類型,所以結(jié)果也是long類型凭语,盡管用int就足夠表示
assert 5L**2 instanceof Long       //  25

// the result can't be represented as an Integer or Long, so return a BigInteger
// 當(dāng)結(jié)果超過了int和long的表示范圍,用BigInteger表示
assert 100**10 instanceof BigInteger   //  10e20
assert 1234**123 instanceof BigInteger //  170515806212727042875...

// the base is a BigDecimal and the exponent a negative int
// but the result can be represented as an Integer
assert 0.5**-2 instanceof Integer    //  4

// the base is an int, and the exponent a negative float
// but again, the result can be represented as an Integer
assert 1**-0.3f instanceof Integer    //  1

// the base is an int, and the exponent a negative int
// but the result will be calculated as a Double
// (both base and exponent are actually converted to doubles)
assert 10**-1 instanceof Double     //  0.1

// the base is a BigDecimal, and the exponent is an int, so return a BigDecimal
assert 1.2**10 instanceof BigDecimal //  6.1917364224

// the base is a float or double, and the exponent is an int
// but the result can only be represented as a Double value
assert 3.4f**5 instanceof Double     //  454.35430372146965
assert 5.6d**2 instanceof Double     //  31.359999999999996

// the exponent is a decimal value
// and the result can only be represented as a Double value
assert 7.8**1.9 instanceof Double     //  49.542708423868476
assert 2**0.1f instanceof Double     //  1.0717734636432956

Elvis Operator

在Java中葱她,我們有時(shí)會(huì)用三元運(yùn)算符來簡(jiǎn)化代碼,比如下邊的例子:

String name = getName(); // 假設(shè)這個(gè)方法可能返回空值似扔,如果我們想在為空時(shí)賦上一個(gè)默認(rèn)值

// 寫法1吨些,普通寫法
if (name == null) {
    name = "unknow";
}

// 寫法2,使用三元運(yùn)算符
name = name 炒辉!= null ? name : "unknow";

在Groovy中豪墅,可以使用Elvis operator來進(jìn)一步簡(jiǎn)化:

def name = getName()
name = name ?: 'unknown' // 在Groovy真值中,非空也為true
println name

安全訪問運(yùn)算符(Safe navigation operator)

我們可以通過一個(gè)點(diǎn).來訪問一個(gè)對(duì)象的屬性或方法黔寇,但很多時(shí)候我們拿到的變量可能是null偶器。這時(shí)如果我們直接使用.去訪問,就有可能拋出空指針異常缝裤。而Groovy的安全訪問運(yùn)算符?.可以很好地解決這個(gè)問題:

def person = getPerson() // 假設(shè)該方法可能返回null
def name = person?.name // 如果person不為null屏轰,那返回具體的值;如果為null憋飞,也不會(huì)拋出異常霎苗,而是返回null

直接屬性訪問運(yùn)算符(Direct field access operator)

先看一個(gè)例子:

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' // 這里看似是訪問屬性name,但其實(shí)是調(diào)用getName方法

上面例子中,我們直接使用user.name其實(shí)相當(dāng)于user.getName()榛做。如果需要直接訪問屬性唁盏,需要使用.@這個(gè)運(yùn)算符:

// 接上邊的例子
assert user.@name == 'Bob'

方法指針運(yùn)算符(Method pointer operator)

使用.&可以取一個(gè)方法的指針内狸,而所謂的方法指針,其實(shí)是Groovy中的閉包

def str = 'example of method reference'
def fun = str.&toUpperCase // 取String的toUpperCase方法指針
println fun.class // class org.codehaus.groovy.runtime.MethodClosure
def upper = fun() // 這里相當(dāng)于調(diào)用了方法
assert upper == str.toUpperCase()

展開運(yùn)算符(Spread Operator)

Groovy中的展開運(yùn)算符(*.)很有意思厘擂,它用于展開集合元素昆淡。

class Car {
    String make
    String model
}

def cars = [
        new Car(make: 'Peugeot', model: '508'),
        new Car(make: 'Renault', model: 'Clio')]
def makes = cars*.make // 相當(dāng)于訪問了每一個(gè)元素的make
assert makes == ['Peugeot', 'Renault'] // 結(jié)果還是一個(gè)列表

范圍運(yùn)算符(Range operator)

使用..可以定義一個(gè)范圍:

def range = 0..5
println range.class // class groovy.lang.IntRange
assert (0..5).collect() == [0, 1, 2, 3, 4, 5]
assert (0..<5).collect() == [0, 1, 2, 3, 4] // 相當(dāng)于左閉右開區(qū)間
assert (0..5) instanceof List // Range實(shí)現(xiàn)了List接口
assert (0..5).size() == 6

飛船運(yùn)算符(Spaceship operator)

<==>像不像一個(gè)宇宙飛船?相當(dāng)于調(diào)用compareTo方法:

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

成員運(yùn)算符(Membership operator)

in相當(dāng)于inCase方法刽严,當(dāng)用在列表上時(shí)昂灵,相當(dāng)于調(diào)用列表的contains方法:

def list = ['Grace', 'Rob', 'Emmy']
assert ('Emmy' in list) // 相當(dāng)于list.contains('Emmy')或list.isCase('Emmy')

身份運(yùn)算符(Identity operator)

在Groovy中==相當(dāng)于調(diào)用equals方法,如果要判斷兩個(gè)對(duì)象是否是同一個(gè)港庄,需要使用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 // 相當(dāng)于list.equals(list2)
assert !list1.is(list2)

運(yùn)算符重載(Operator overloading)

Groovy中支持運(yùn)算符重載倔既,其實(shí)也就是實(shí)現(xiàn)約定好的方法:

class Bucket {
    int size

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

    Bucket plus(Bucket other) { // 重載這個(gè)以實(shí)現(xiàn)+操作
        return new Bucket(this.size + other.size)
    }
}

def b1 = new Bucket(4)
def b2 = new Bucket(11)
assert (b1 + b2).size == 15 // 這里相當(dāng)于(b1.plus(b2)).size

下面是支持重載的運(yùn)算符與相應(yīng)方法的對(duì)照表:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鹏氧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌佩谣,老刑警劉巖把还,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茸俭,居然都是意外死亡吊履,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門调鬓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艇炎,“玉大人,你說我怎么就攤上這事腾窝∽鹤伲” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵虹脯,是天一觀的道長(zhǎng)驴娃。 經(jīng)常有香客問我,道長(zhǎng)循集,這世上最難降的妖魔是什么唇敞? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮咒彤,結(jié)果婚禮上疆柔,老公的妹妹穿的比我還像新娘。我一直安慰自己镶柱,他們只是感情好旷档,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奸例,像睡著了一般彬犯。 火紅的嫁衣襯著肌膚如雪向楼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天谐区,我揣著相機(jī)與錄音湖蜕,去河邊找鬼。 笑死宋列,一個(gè)胖子當(dāng)著我的面吹牛昭抒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炼杖,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼灭返,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了坤邪?” 一聲冷哼從身側(cè)響起熙含,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艇纺,沒想到半個(gè)月后怎静,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡黔衡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年蚓聘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盟劫。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夜牡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侣签,到底是詐尸還是另有隱情塘装,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布硝岗,位于F島的核電站氢哮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏型檀。R本人自食惡果不足惜冗尤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胀溺。 院中可真熱鬧裂七,春花似錦、人聲如沸仓坞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽无埃。三九已至徙瓶,卻和暖如春毛雇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侦镇。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工灵疮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人壳繁。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓震捣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親闹炉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蒿赢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • C++運(yùn)算符重載-下篇 本章內(nèi)容:1. 運(yùn)算符重載的概述2. 重載算術(shù)運(yùn)算符3. 重載按位運(yùn)算符和二元邏輯運(yùn)算符4...
    Haley_2013閱讀 1,435評(píng)論 0 49
  • C++運(yùn)算符重載-上篇 本章內(nèi)容:1. 運(yùn)算符重載的概述2. 重載算術(shù)運(yùn)算符3. 重載按位運(yùn)算符和二元邏輯運(yùn)算符4...
    Haley_2013閱讀 2,291評(píng)論 0 51
  • 前言 人生苦多,快來 Kotlin 渣触,快速學(xué)習(xí)Kotlin羡棵! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,163評(píng)論 9 118
  • Groovy是一門基于JVM的動(dòng)態(tài)語言昵观,很多語法和Java類似晾腔。大部分Java代碼也同時(shí)是合法的Groovy代碼。...
    樂百川閱讀 3,582評(píng)論 0 15
  • 去年年底開始啊犬,互聯(lián)網(wǎng)蓬勃發(fā)展,“碎片化學(xué)習(xí)”成了熱門話題壁查。一下子讓人覺得現(xiàn)在我們的時(shí)間因?yàn)榛ヂ?lián)網(wǎng)的發(fā)展觉至,被碎片到了...
    流動(dòng)盛宴愛碼士閱讀 6,129評(píng)論 1 2