【Java】Collections/Comparable/compareTo/Comparatorとか自然順序とか

徒然草2.0

※個人的なJavaの学習メモです。

字面を追うだけでは頭に入らないので書き出してみる。

結論から言うと、コンパラブル(Comparable)というインターフェースのコンペアトゥ(compareTo)メソッドで自然順序付けができ、コンパレータ(Comparator)というインターフェースのコンペア(compare)メソッドによりソートのキーと順番を設定できるそうだ。

ぱっと聞いて分からないし言葉で言うにしても舌を噛みそうではないか。

あとは自然順序(natural order)はエンジニア同士の会話には登場するとは思うが、その定義についてなんとなくしか分かっていなかったので、初めて知ったと言ってもいい気がする。

Collections(クラス)

JavaにはCollectionsというクラスがある。java.util.Collectionsパッケージに含まれている。ListやSetやMapに順番を入れ替えるsortメソッドなどの機能を追加する。

以下のように記述するだけで使用できるようになる。

import java.util.Collections;

追加されるメソッドの事をユーティリティメソッドまたはユーティリティ関数という。

※ユーティリティメソッドはsortの他にも、shffleによるランダムに入れ替え、reverseなどの逆順、maxやminで最大値や最小値を返したり、binarySearchによる探索、fillによる同値埋め、copyやunmodifiableListでイミュターブルなリストを作成する便利機能を提供してくれる。これは便利なのでListを定義するときにはとりあえず組み込んでおきたいが、わざわざ定義しないと使えない。

※なお、これらのユーティリティメソッドは静的メソッドであるため、クラスに属しておりオーバーライドできないらしい。自分で自由に改造することは禁じられている。

Comparable(インターフェース)

Comparableは難しい言葉で言うと「自然順序付けを定義するためのインターフェース」だが、これだけ言われても何のことだかピンとこないのではないか。私はよく分からなかった。

簡単に言えば、このインターフェースを実装するオブジェクトは「ある値とかと比較できますよ!」という意図を明らかにするためにあるようだ。

例えば、Personクラスのageプロパティをインスタンス化した太郎は(Comparable)compareToメソッドにより18歳(成人年齢)よりも年上か評価できるように実装する必要がある(このメソッドが実装されていないとコンパイルに失敗する)。

ようは、オブジェクトに数値を比較する特性(+メソッド)を付与するクラス設計であることを伝えることができる便利なクラス拡張用のインターフェースである。

compareTo(メソッド)

すでに説明したとおり、Comparableインターフェースにより付与されるメソッドでオブジェクトの特定プロパティを比較して評価する。

与えられたパラメータよりも小さい場合は負の数、同じなら0、大きい場合は正の数を返すように自分で実装する必要がある。(メソッドは自動で追加されるので色々と勝手にやってくれるものだと思ったが、あくまで実装は自分でやらないといけないらしい)

Comparator(インターフェース)

Collectionクラスにより追加されるコレクションのsortメソッドは、デフォルトで自然順序になっているが、そのキーとソート順序を変更することが可能なcompareメソッドを追加する。

compare(メソッド)

Comparatorインターフェースにより追加されるsortメソッドのキーとソート順(並び順)を設定可能にするのがcomparaメソッドである。

補足:自然順序とは?

・数値の場合は昇順 (1,2,3,4...)

・文字の場合は辞書順/アルファベット順 (あ、い、う)(A, B, C, D …)

・日付の場合は過去→未来(昇順) (2024, 2025, 2026 …)

昇順と降順

昇順(ascending order)は数字が昇っていく、降順(descending order)は数字が降りていく、と捉えると間違えない。

まとめ

  • Collectionsクラスにより、sortメソッドを追加できる。
  • Comparableインターフェースにより、compareToメソッドを追加し、自然順序付けを定義できる。
  • Comparatorインターフェースにより、compareメソッドを追加し、sortメソッドのキーと並び順を変更できる。

sort orderに関するJavaの約束事項というか覚えておくべきセット概念だが名前が似ていてややこしいので、まとめてみました。

※ある書籍を読んでいたらこれらの概念が一緒くたに登場した。sortに直接関係するのはcompareメソッドであり、compareToメソッドは順序付けの定義のみsortメソッドと直接は関係がないような気もする。

…ということで、Javaで競技プログラミングをやってみようと思ったけれど、List型を定義するのにこれらの設定も記述しないといけないしたらコード量が半端なくてエグいのでは?Javaを選択している人はどうしているのか?(配列はArrayを使用し、sortは関数で行っている?)

徒然草2.0
スポンサーリンク
シェアする
gomiryoをフォローする
ごみぶろぐ

コメント

タイトルとURLをコピーしました