今天生成word文档时,遇到了集合中多个字段按拼音排序的问题,好久没有写过比较器了,顺带着温习一下。
问题
有一个对象集合,集合中有一些字符串类型的字段,要根据拼音顺序进行排序,该如何实现?
模拟
有一个对象类 Person,具有四个字段:name、age、height 和 weight,现在我们要对一个存储了多个 Person 对象的集合进行排序。我们将按照以下规则排序:首先按照 age 升序排序,然后按照 height 降序排序,接着按照 weight 升序排序,最后按照 name 字母顺序排序。
public class Person {
private String name;
private int age;
private double height;
private double weight;
// 构造函数、getter 和 setter 方法省略
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
", weight=" + weight +
'}';
}
}
方式1:自定义比较器
import java.util.Comparator;
public class PersonComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
int result = p1.getName().compareTo(p2.getName());
if (result == 0) {
result = Double.compare(p2.getHeight(), p1.getHeight());
if (result == 0) {
result = Double.compare(p1.getWeight(), p2.getWeight());
if (result == 0) {
result = Integer.compare(p1.getAge(), p2.getAge());
}
}
}
return result;
}
}
测试方法:
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("阿里", 30, 170.5, 60.0));
personList.add(new Person("美星", 25, 165.0, 70.0));
personList.add(new Person("腾讯", 30, 180.0, 80.0));
// 使用自定义比较器进行排序
Collections.sort(personList, new PersonComparator());
// 输出排序后的结果
for (Person person : personList) {
System.out.println(person);
}
}
输出结果:
Person{name='美星', age=25, height=165.0, weight=70.0}
Person{name='腾讯', age=30, height=180.0, weight=80.0}
Person{name='阿里', age=30, height=170.5, weight=60.0}
阿里按拼音来排序,肯定是排在第一个,这样是不对的?
改善比较器:
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
public class PersonComparator implements Comparator<Person> {
//定义排列规则,根据汉语拼音进行排序
private Collator collator = Collator.getInstance(Locale.CHINA);
@Override
public int compare(Person p1, Person p2) {
int result = collator.compare(p1.getName(), p2.getName());
if (result == 0) {
result = Double.compare(p2.getHeight(), p1.getHeight());
if (result == 0) {
result = Double.compare(p1.getWeight(), p2.getWeight());
if (result == 0) {
result = Integer.compare(p1.getAge(), p2.getAge());
}
}
}
return result;
}
}
输出结果:
Person{name='阿里', age=30, height=170.5, weight=60.0}
Person{name='美星', age=25, height=165.0, weight=70.0}
Person{name='腾讯', age=30, height=180.0, weight=80.0}
这样就没有问题啦!
方式2:使用 Comparator.comparing 方法:
样例
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("张三", 30, 170.5, 60.0));
personList.add(new Person("李四", 25, 165.0, 70.0));
personList.add(new Person("王五", 30, 180.0, 80.0));
// 使用 Comparator.comparing 方法结合 Collator 进行排序
Collator collator = Collator.getInstance(Locale.CHINA);
personList.sort(
Comparator.comparing((Person p) -> p.getName(), collator)
.thenComparing(Person::getAge)
.thenComparing(Person::getHeight, Comparator.reverseOrder())
.thenComparing(Person::getWeight)
);
// 输出排序后的结果
for (Person person : personList) {
System.out.println(person);
}
}
这样写起来,更加简洁。
输出结果:
Person{name='李四', age=25, height=165.0, weight=70.0}
Person{name='王五', age=30, height=180.0, weight=80.0}
Person{name='张三', age=30, height=170.5, weight=60.0}
问题已解决,今天先到这。
晚安!