嵌套字段的 Comparator.comparing(...)

新手上路,请多包涵

假设我有一个这样的领域模型:

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

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

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

现在我可以像这样创建一个教师比较器:

     return Comparator
            .comparing(Teacher::getAge);

但是我如何比较 Lecture 的嵌套字段,就像这样?

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

我无法在模型上添加方法 Lecture.getTeacherAge()

原文由 Geoffrey De Smet 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 746
2 个回答

您不能嵌套方法引用。您可以改用 lambda 表达式:

 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());

注意:在某些情况下,您需要明确声明通用类型。例如,如果没有 comparing(...) 在 Java 8 中的 <FlightAssignment, LocalDateTime> 之前,下面的代码将无法工作。

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

较新的 Java 版本具有更好的自动类型检测功能,可能不需要。

原文由 Eran 发布,翻译遵循 CC BY-SA 4.0 许可协议

不幸的是,java 中没有很好的语法。

如果你想重用部分比较器,我可以看到两种方法:

  • 通过组成比较器
  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);

  • 通过组合 getter 函数
  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);

原文由 Nazarii Bardiuk 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题