Java 8中如何基于多字段对对象列表排序(含外部类属性)
问题:结合外部类方法实现多规则排序
假设存在以下类:
Person类:包含getAge()和getYearsOfEducation()方法,均返回int类型;Employer类:包含getYearsOfEmployment(Person p)方法,返回指定Person的雇佣年限(int类型)。
代码示例:
Employer e = new Employer(); Person p1 = new Person(26, 3); // 年龄26,受教育年限3 Person p2 = new Person(30, 4); // 年龄30,受教育年限4 Person p3 = new Person(28, 5); // 年龄28,受教育年限5,e.getYearsOfEmployment(p3)返回10 Person p4 = new Person(28, 5); // 年龄28,受教育年限5,e.getYearsOfEmployment(p4)返回8
需求:对随机添加的Person列表按以下规则升序排序:
- 年龄优先;
- 年龄相同时,按受教育年限排序;
- 前两者都相同时,按雇佣年限排序。
示例期望排序结果:p1 → p4 → p3 → p2。
当前已实现前两个字段的排序逻辑,需要补充第三个字段的排序代码:
List<Person> persons = Arrays.asList(p1, p2, p3, p4); Collections.sort(persons, Comparator.comparing(Person::getAge) .thenComparing(Person::getYearsOfEducation) .thenComparing(...));
请问该需求是否可实现?
解答
完全可以实现,只需要在thenComparing中传入基于Employer实例的函数,将Person映射为对应的雇佣年限即可。
完整代码实现
List<Person> persons = Arrays.asList(p1, p2, p3, p4); Collections.sort(persons, Comparator.comparing(Person::getAge) .thenComparing(Person::getYearsOfEducation) .thenComparing(e::getYearsOfEmployment)); // 补充的雇佣年限排序逻辑
原理说明
e::getYearsOfEmployment是Java的实例方法引用,等价于lambda表达式person -> e.getYearsOfEmployment(person);- 该方法引用会将
Person对象作为参数传入Employer的getYearsOfEmployment方法,返回对应的雇佣年限,供比较器进行升序排序; - 按照示例数据,
p4的雇佣年限(8)小于p3的(10),因此排序时p4会排在p3前面,完全符合预期结果。
内容的提问来源于stack exchange,提问作者rdv
相关产品推荐
相关产品推荐

