Comparator.comparing(…) of a nested field

陌路散爱 提交于 2019-11-27 09:13:25
Eran

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.

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);
    
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;

  class Person {
      String name ;
      PersonalDetail pDetail;
    public Person(String name, PersonalDetail pDetail) {
        super();
        this.name = name;
        this.pDetail = pDetail;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public PersonalDetail getpDetail() {
        return pDetail;
    }
    public void setpDetail(PersonalDetail pDetail) {
        this.pDetail = pDetail;
    }




  }

  class PersonalDetail{
      BirthDate birthDate;

    public BirthDate getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(BirthDate birthDate) {
        this.birthDate = birthDate;
    }

    public PersonalDetail(BirthDate birthDate) {
        super();
        this.birthDate = birthDate;
    }


  }

    class BirthDate {
        public String getBirthdate() {
            return birthdate;
        }

        public void setBirthdate(String birthdate) {
            this.birthdate = birthdate;
        }

    String birthdate;

        public BirthDate(String birthdate) {
            super();

            this.birthdate = birthdate;
        }  
  }

  public class Test1 {
       public static void main(String[] args) {
           BirthDate b1 = new BirthDate("2019-08-08");
           BirthDate b2 = new BirthDate("2025-09-09");
           BirthDate b3 = new BirthDate("2025-09-08");
           BirthDate b4 = new BirthDate("2024-09-08");

           PersonalDetail pd1  = new PersonalDetail(b1);
           PersonalDetail pd2  = new PersonalDetail(b2);
           PersonalDetail pd3  = new PersonalDetail(b3);
           PersonalDetail pd4  = new PersonalDetail(b4);

           Person p1  = new Person("P1",pd1);
           Person p2  = new Person("P2",pd2);
           Person p3  = new Person("P3",pd3);
           Person p4  = new Person("P4",pd4);

           List<Person> persons = new ArrayList();
           persons.add(p1);
           persons.add(p2);
           persons.add(p3);
           persons.add(p4);

           Function<Person, PersonalDetail> getCourse = Person::getpDetail;  

           Person minByAge = persons.stream()
                      .max(Comparator.comparing(getCourse.andThen(PersonalDetail::getBirthDate).andThen(BirthDate::getBirthdate))).get();


          System.out.println(maxByAge.getName());

       }

    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!