ネストされたフィールドの Comparator.comparing(...) 質問する

ネストされたフィールドの Comparator.comparing(...) 質問する

次のようなドメイン モデルがあるとします。

class Lecture {
     Course course;
     ... // getters
}

class Course {
     Teacher teacher;
     int studentSize;
     ... // getters
}

class Teacher {
     int age;
     ... // getters
}

これで、次のような Teacher Comparator を作成できます。

    return Comparator
            .comparing(Teacher::getAge);

しかし、このようにネストされたフィールド上の Lecture をどのように比較すればよいのでしょうか?

    return Comparator
            .comparing(Lecture::getCourse::getTeacher:getAge) 
            .thenComparing(Lecture::getCourse::getStudentSize);

Lecture.getTeacherAge()モデルにメソッドを追加できません。

ベストアンサー1

メソッド参照をネストすることはできません。代わりにラムダ式を使用できます。

return Comparator
        .comparing(l->l.getCourse().getTeacher().getAge(), Comparator.reverseOrder()) 
        .thenComparing(l->l.getCourse().getStudentSize());

逆順の必要がないので、さらに簡潔になります。

return Comparator
        .comparing(l->l.getCourse().getTeacher().getAge()) 
        .thenComparing(l->l.getCourse().getStudentSize());

注: 場合によっては、ジェネリック型を明示的に指定する必要があります。たとえば、以下のコードは、Java 8 では<FlightAssignment, LocalDateTime>beforeがないと機能しません。comparing(...)

flightAssignmentList.sort(Comparator
        .<FlightAssignment, LocalDateTime>comparing(a -> a.getFlight().getDepartureUTCDateTime())
        .thenComparing(a -> a.getFlight().getArrivalUTCDateTime())
        .thenComparing(FlightAssignment::getId));

新しい Java バージョンでは自動型検出機能が強化されているため、この機能は必要なくなる可能性があります。

おすすめ記事