Groovyの便利なオペレーター

Groovyを使う上で便利なオペレーターについてまとめます。

?:(エルビス)オペレーター

falseと判定される場合に、デフォルト値を指定する場合に利用する。

def user = [name: null]
// 3項演算子の場合
assert user.name ? user.name : "Anonymous" == "Anonymous"
// ?:オペレータの場合
assert user.name ?: "Anonymous" == "Anonymous"

数値型に使う場合は0の場合も変換されてしまうので注意

def number = 0
assert number ?: -1 == -1

?オペレータ

nullの可能性があるオブジェクトのメソッドを呼ぶ場合に利用する。

def person = null
def name = person?.name
assert name == null

.@オペレータ

getter / setter がある場合に、インスタンス変数を直接参照/更新する場合に利用する。

class User {
    def name = null

    User(String name) {
        this.name = name
    }

    def getName() {
        "${name}様"
    }

    void setName(String name) {
        this.name = name.take(name.length() - 1)
    }
}

def user = new User("信繁")
// getterから取得
assert user.name == "信繁様"
// インスタンス変数を直接取得
assert user.@name == "信繁"

// setterで設定
user.name = "信繁様"
assert user.name == "信繁様"
// インスタンス変数を直接設定
user.@name = "信繁様"
assert user.name == "信繁様様"

&オペレータ

あまり使うことは無いかもしれませんが、メソッドポインタを使いたい場合に使います。

class User {
    def name = null

    User(String name) {
        this.name = name
    }

    def getName() {
        "${name}様"
    }

    static getName(User user) {
        "${user.@name}君"
    }
}

def user = new User("信繁")
// インスタンスメソッドの場合
def getNameInstance = user.&getName
assert getNameInstance() == "信繁様"

// クラスメソッドの場合
def getNameStatic = User.&getName
assert getNameStatic(user) == "信繁君"

*.オペレータ

リスト中の特定の項目のみを集めたリストを作成する場合に利用します。collectメソッドでも同じことが出来ます。

class Car {
    String make
    String model
}
def cars = [
       new Car(make: 'Peugeot', model: '508'),
       new Car(make: 'Renault', model: 'Clio')]
// collectメソッドの場合
assert cars.collect { it.make } == ['Peugeot', 'Renault']
// .*オペレータの場合
assert cars*.make == ['Peugeot', 'Renault']

リスト中にnullがある場合はnullとして処理してくれます。

class Car {
    String make
    String model
}
def cars = [
        new Car(make: 'Peugeot', model: '508'),
        null,
        new Car(make: 'Renault', model: 'Clio')]
// collectメソッドの場合
assert cars.collect { it?.make } == ['Peugeot', null, 'Renault']
// .*オペレータの場合
assert cars*.make == ['Peugeot', null, 'Renault']

リスト自体がnullの場合はnullを返します。

// collectメソッドの場合
assert null?.collect { it?.make } == null
// .*オペレータの場合
assert null*.make == null

*オペレータ

リストを展開する場合に利用する。

def function(int x, y, z) {
    x * y + z
}

def args = [4, 5, 6]
assert function(*args) == 26

args = [5]
assert function(4, *args, 6) == 26

def items = [4, 5]
def list = [1, 2, 3, *items, 6]
assert list == [1, 2, 3, 4, 5, 6]

*:オペレータ

Mapを展開する場合に利用する。

def subMap = [c: 3, d: 4]
def map = [a: 1, b: 2, *:subMap, e: 5]
assert map == [a:1, b: 2, c: 3, d: 4, e: 5]

<=>オペレータ

compareToメソッドと等価です。

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

複数項目でソートする場合に便利です。

class User {
    def first
    def last
}

def list = [new User(first: "のぶゆき", last: "真田"), new User(first: "のぶしげ", last: "真田")]
assert list.sort { x, y -> x.last <=> y.last ?: x.first <=> y.first }*.first == ["のぶしげ", "のぶゆき"]

list = [new User(first: "信繁", last: "真田"), new User(first: "信繁", last: "武田")]
assert list.sort { x, y -> x.last <=> y.last ?: x.first <=> y.first }*.last == ["武田", "真田"]

inオペレータ

containsメソッドとisCaseメソッドと等価です。

def list = ["Grace", "Rob", "Emmy"]
assert "Emmy" in list
assert list.contains("Emmy")
assert list.isCase("Emmy")

コメント