Programmingバックエンド開発者

JavaにおけるComparableインターフェースとComparatorインターフェースの違いを説明し、ユーザー定義オブジェクトのソートにどのように適切に実装し適用するかを説明してください。

Hintsage AIアシスタントで面接を突破

回答

Comparableは、オブジェクトのクラス自体によって実装されるインターフェースです。自然なソート順を定義するcompareTo()メソッドを1つ定義します。

Comparatorは、compare(o1, o2)メソッドを実装する独立したインターフェースです。クラスのコードを変更することなく、複数のソート方法を定義することができます。

使用するタイミング:

  • クラスが論理的に1つの自然なソート方法しか持たない場合 — Comparableを実装します。
  • 複数のソート方法をサポートする必要がある場合 — 対応するComparatorを作成します。

例:

// Comparable class Student implements Comparable<Student> { String name; int grade; public int compareTo(Student other) { return this.grade - other.grade; } } // Comparator Comparator<Student> byName = new Comparator<Student>() { public int compare(Student s1, Student s2) { return s1.name.compareTo(s2.name); } }; List<Student> students = ...; Collections.sort(students); // gradeによるソート Collections.sort(students, byName); // nameによるソート

トリッキーな質問

Comparableを実装していないオブジェクトのListをComparatorなしでソートできますか?

回答: いいえ。クラスがComparableを実装しておらず、明示的にComparatorが渡されていない場合、コレクションのソートを試みるとClassCastExceptionがスローされます。

例:

class Animal {} List<Animal> animals = ...; Collections.sort(animals); // Comparableがない場合、ClassCastException

歴史

インベントリプロジェクトで、ItemクラスにComparableを実装するのを忘れました。Collections.sort(items)によるソートを試みた結果、compareTo()メソッドがないため、アプリケーションがClassCastExceptionで繰り返しクラッシュしました。


歴史

生徒の評価計算サービスで、開発者はgradeフィールドでの比較をcompareTo()メソッド内にのみ実装しました。後に名前や生年月日でソートする必要があったが、クラスのコードが補助メソッドで膨れ上がり、異なるComparatorを使用する代わりにcompareTo()で複雑なロジックを避けることができませんでした。


歴史

オンライン注文の製品で、日付で注文をソートするためにComparatorをラムダ式で使用しようとしましたが、日付がnullになる可能性を考慮するのを忘れました。その結果、納品日のない注文のソート時に予期しないNullPointerExceptionがプロダクションで発生しました。