Comparator.comparing(...) of a nested field
Solution 1:
You can't nest method references. You can use lambda expressions instead:
return Comparator
.comparing(l->l.getCourse().getTeacher().getAge(), Comparator.reverseOrder())
.thenComparing(l->l.getCourse().getStudentSize());
Without the need for reverse order it's even less verbose:
return Comparator
.comparing(l->l.getCourse().getTeacher().getAge())
.thenComparing(l->l.getCourse().getStudentSize());
Note: in some cases you need to explicitly state the generic types. For example, the code below won't work without the <FlightAssignment, LocalDateTime>
before comparing(...)
in Java 8.
flightAssignmentList.sort(Comparator
.<FlightAssignment, LocalDateTime>comparing(a -> a.getFlight().getDepartureUTCDateTime())
.thenComparing(a -> a.getFlight().getArrivalUTCDateTime())
.thenComparing(FlightAssignment::getId));
Newer java version have better auto type detection and might not require that.
Solution 2:
Unfortunately there is no nice syntax in java for that.
If you want to reuse parts of comparator I can see 2 ways:
-
by composing comparators
return comparing(Lecture::getCourse, comparing(Course::getTeacher, comparing(Teacher::getAge))) .thenComparing(Lecture::getCourse, comparing(Course::getStudentSize)); // or with separate comparators Comparator<Teacher> byAge = comparing(Teacher::getAge); Comparator<Course> byTeacherAge = comparing(Course::getTeacher, byAge); Comparator<Course> byStudentsSize = comparing(Course::getStudentSize); return comparing(Lecture::getCourse, byTeacherAge).thenComparing(Lecture::getCourse, byStudentsSize);
-
by composing getter functions
Function<Lecture, Course> getCourse = Lecture::getCourse; return comparing(getCourse.andThen(Course::getTeacher).andThen(Teacher::getAge)) .thenComparing(getCourse.andThen(Course::getStudentSize)); // or with separate getters Function<Lecture, Course> getCourse = Lecture::getCourse; Function<Lecture, Integer> teacherAge = getCourse.andThen(Course::getTeacher).andThen(Teacher::getAge); Function<Lecture, Integer> studentSize = getCourse.andThen(Course::getStudentSize); return comparing(teacherAge).thenComparing(studentSize);