以下是如何在Java中对List集合按照对象多个字段属性进行排序的详细指南,包含代码示例和最佳实践:
1. 基础模型准备
java
Copy Code
public class Person {
private String name;
private int age;
private double salary;
// 构造方法、getters/setters省略
@Override
public String toString() {
return String.format("%s(age:%d, salary:%.2f)", name, age, salary);
}
}
2. 使用Comparator实现多级排序(Java 8+)
示例1:年龄升序+薪资降序
java
Copy Code
List
new Person("王伟", 28, 8500),
new Person("李芳", 28, 8200),
new Person("张强", 30, 9500)
);
people.sort(Comparator
.comparingInt(Person::getAge)
.thenComparing(Comparator.comparingDouble(Person::getSalary).reversed())
);
// 输出结果:
// 李芳(age:28, salary:8200.00)
// 王伟(age:28, salary:8500.00)
// 张强(age:30, salary:9500.00)
示例2:处理null值(姓名不区分大小写+年龄倒序)
java
Copy Code
Comparator
.comparing(p -> p.getName() != null ? p.getName().toLowerCase() : null,
Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER))
.thenComparingInt(Person::getAge).reversed();
3. 传统Comparator实现方式(Java 7)
java
Copy Code
Collections.sort(people, new Comparator
@Override
public int compare(Person p1, Person p2) {
int ageCompare = Integer.compare(p1.getAge(), p2.getAge());
if (ageCompare != 0) return ageCompare;
return Double.compare(p2.getSalary(), p1.getSalary()); // 薪资降序
}
});
4. 实现Comparable接口(固定排序规则)
java
Copy Code
public class Person implements Comparable
@Override
public int compareTo(Person other) {
int nameCompare = this.name.compareTo(other.name);
if (nameCompare != 0) return nameCompare;
return Integer.compare(this.age, other.age);
}
}
5. 高级排序技巧
自定义空值处理:使用Comparator.nullsFirst()/nullsLast()
组合排序器:通过thenComparing()实现任意多级排序
反向排序:使用reversed()方法
自定义排序逻辑:
java
Copy Code
Comparator.comparing(p -> p.getSalary() > 10000 ? 1 : 0)
.thenComparing(Person::getName)
6. 完整示例代码
java
Copy Code
import java.util.*;
import java.util.stream.Collectors;
public class MultiFieldSort {
public static void main(String[] args) {
List
new Person("王伟", 28, 8500),
new Person(null, 25, 7200),
new Person("李芳", 28, 8200),
new Person("张强", 30, 9500)
);
// 多字段排序:处理null值->姓名升序->年龄降序->薪资升序
List
.sorted(Comparator
.comparing(Person::getName,
Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER))
.thenComparingInt(Person::getAge).reversed()
.thenComparingDouble(Person::getSalary))
.collect(Collectors.toList());
sorted.forEach(System.out::println);
}
}
7. 性能优化建议
优先使用基本类型比较器:comparingInt()比comparing()更高效
避免在循环中重复创建Comparator实例
对大数据集考虑使用并行流:parallelStream()
对频繁排序的场景,可缓存Comparator实例
8. 应用场景总结
场景 推荐方法
简单多字段排序 Comparator链式调用
需要空值处理 nullsFirst()/nullsLast()
需要动态排序规则 构建Comparator工厂方法
固定业务规则排序 实现Comparable接口
复杂排序逻辑 自定义Comparator实现类
通过合理使用Java的Comparator API,开发者可以轻松实现各种复杂的多字段排序需求,同时保持代码的简洁性和可维护性。
本文暂时没有评论,来添加一个吧(●'◡'●)