章
目
录
Java Comparator接口用于根据自定义排序顺序对数组或对象列表进行排序。通过在对象中实现Comparator的compare()方法来强加项目的自定义排序顺序。
1.何时使用Comparator接口
Java Comparator接口对可能没有所期望的自然排序的对象强加了完全排序。
例如,对于一组Employee对象,自然顺序可能按照员工的ID排序。但在实际应用中,我们可能希望按照员工的名字、出生日期或其他任何标准对员工列表进行排序。在这种情况下,我们需要使用Comparator接口。
我们可以在以下情况下使用Comparator接口:
- 对数组或对象列表进行排序,但不是按照自然顺序。
- 对无法修改源代码以实现Comparable接口的数组或对象列表进行排序。
- 在多个不同字段上对列表或对象数组进行分组排序。
2.覆盖compare()方法
为了对对象启用完全排序,我们需要创建一个实现Comparator接口的类。然后,我们需要覆盖其compare(T o1, T o2)方法。
compare()方法比较其两个参数的顺序。它返回一个负整数、零或正整数,表示第一个参数小于、等于或大于第二个参数。
实现者还必须确保关系是传递性的:((compare(x, y) > 0) && (compare(y, z) > 0))意味着compare(x, z) > 0。
对于给定的Employee类,可以通过创建如下所示的Comparator来按员工姓名排序。
import java.util.Comparator;
public class NameSorter implements Comparator<Employee>
{
@Override
public int compare(Employee e1, Employee e2) {
return e1.getName().compareToIgnoreCase( e2.getName() );
}
}
import java.time.LocalDate;
public class Employee {
private Long id;
private String name;
private LocalDate dob;// 出生日期
}
3. 使用Comparator
3.1. Collections.sort()和Arrays.sort()
- 使用Collections.sort(list, Comparator)方法按提供的比较器实例所强加的顺序对对象列表进行排序。
- 使用Arrays.sort(array, Comparator)方法按提供的比较器实例所强加的顺序对对象数组进行排序。
3.2. Collections.comparing()
此实用方法接受一个函数,用于提取类的排序键。这本质上是类对象将按照其上的字段进行排序。
//按姓名排序
Comparator.comparing(Employee::getName);
//按姓名倒序排序
Comparator.comparing(Employee::getName).reversed();
//按ID字段排序
Comparator.comparing(Employee::getId);
//按员工年龄排序
Comparator.comparing(Employee::getDob);
3.3. Collections.thenComparing()
此实用方法用于分组排序。使用此方法,我们可以链接多个比较器,以按多个字段对对象列表或数组进行排序。
它与SQL的GROUP BY子句非常相似,用于按不同字段对行进行排序。
//按姓名排序,然后按年龄排序
Comparator.comparing(Employee::getName)
.thenComparing(Employee::getDob);
//按姓名排序,然后按出生日期排序,最后按ID排序
Comparator.comparing(Employee::getName)
.thenComparing(Employee::getDob)
.thenComparing(Employee::getId);
使用上述语法,我们可以创建几乎任何排序逻辑。
3.4. Collections.reverseOrder()
此实用方法返回一个比较器,对实现Comparable接口的对象集合强加自然排序或完全排序的逆序。
//按照Comparable接口的compareTo()方法指定的自然顺序的逆序
Comparator.reversed();
//按姓名排序的逆序
Comparator.comparing(Employee::getName).reversed();
3.5. 其他集合类
比较器还可以用于控制某些数据结构(例如排序集或排序映射)的顺序,以提供不是自然排序的顺序。
SortedSet<Employee> sortedUniqueEmployees = new TreeSet<Employee>(new NameSorter());
4. Java Comparator示例
4.1. 对自定义对象列表进行排序
使用Comparator对员工列表按姓名排序的Java示例。
ArrayList<Employee> list = new ArrayList<>();
//创建一个自定义的NameSorter类用于排序
Collections.sort(list, new NameSorter());
4.2. 按逆序排序列表
使用Comparator对员工列表按姓名按逆序排序的Java示例。
ArrayList<Employee> list = new ArrayList<>();
Collections.sort(list, Comparator.comparing( Employee::getName ).reversed());
4.3. 分组排序
使用Java示例对多个字段,即逐字段,对员工列表进行排序。
ArrayList<Employee> list = new ArrayList<>();
Comparator<Employee> groupByComparator = Comparator.comparing(Employee::getName)
.thenComparing(Employee::getDob)
.thenComparing(Employee::getId);
Collections.sort(list, groupByComparator);
5. 结论
在本教程中,我们了解了Java集合框架的Comparator接口。它有助于在不更改类的源代码的情况下对对象进行完全排序。
我们学会了对自定义对象的列表和数组进行排序。还学会了逆序排序和实现分组排序在Java中。