[Groovy]ソートについて

  未分類

javaでComparableインタフェースを使うような場面でも、Groovyならクロージャでサクッと書ける。

例えばフォルダ配下のファイルを名前昇順に処理したいときはこのようにします。

File dir = new File("/tmp")
dir.listFiles().sort { 
    left, right ->
    left.name <=> right.name
}.each { 
    // 処理
}

listFiles()メソッドはFile配列を返します。それに対してsortメソッドのクロージャを記述しています。
sortのクロージャでは比較するオブジェクト2つの引数をとります。今回は名前で比較しています。(<=> が比較を意味します)
逆順にソートしたいときは、入れ替えて right.name <=> left.name とすればよいです。

2つ以上の条件で比較したいとき。例えば更新日時と名前でソートしたいときは次のようになります。

File dir = new File("/tmp")
dir.listFiles().sort {
    left, right ->
    left.lastModified() <=> right.lastModified() ?: left.name <=> right.name
}.each {
    // 処理
}

「 <=> 」は宇宙船演算子と呼ぶらしいです。
A <=> B と記述した時、A<Bなら-1、A==Bなら0、A>Bなら1を返します。
上記の例ではクロージャは特にreturnを使わず、最後の演算を比較結果としていますが、明示的に-1,0,1を返す書き方ももちろん可能です。

3を特別扱いするソートの例

println(
[1,2,3,4,5,6].sort {
    a, b ->
    if (b == 3) return 1
    if (a == 3) return -1
    return a <=> b
})

実行結果

[3, 1, 2, 4, 5, 6]

LEAVE A COMMENT