通常说,比较器用于具有对象集合的多个排序序列,而可比较用于具有单个排序序列。当使用可比较的接口可以有多个排序序列时,在java中比较器接口的用途是什么?
import java.util.*;
enum CompareValue {RollNo, Marks;}
class Student implements Comparable<Student> {
public int marks;
public int rollNo;
public static CompareValue comparator = CompareValue.RollNo;
Student (int marks, int rollNo) {
this.marks = marks;
this.rollNo = rollNo;
}
public int compareTo(Student s) {
switch (comparator) {
case RollNo:
return this.rollNo - s.rollNo;
case Marks:
return this.marks - s.marks;
}
return 0;
}
}
public class Test
{
public static void main (String[] args)
{
Student s1 = new Student(59, 103);
Student s2 = new Student(87, 102);
Student s3 = new Student(78, 101);
Student students[] = {s1, s2, s3};
Arrays.sort(students);
System.out.println("Student list sorted by rollno");
for (Student s:students) {
System.out.println(s.rollNo + " - " + s.marks);
}
Student.comparator = CompareValue.Marks;
System.out.println("Student list sorted by marks");
Arrays.sort(students);
for (Student s:students) {
System.out.println(s.rollNo + " - " + s.marks);
}
}
}发布于 2019-03-13 15:21:09
当您的compareTo方法根据某个static变量的值具有不同的行为时,基本上就是引入了一个全局设置来控制Student类的自然顺序。
这可能会使您的类的用户感到困惑和违反直觉。
此外,这使得compareTo的实现变得很笨拙,特别是当您有两个以上的实现,并且每个实现都依赖于多个实例变量时。
对于为同一个类的实例提供多个不同的比较,Comparator是一个更合适的接口,每个实现都有自己的compare()逻辑。
发布于 2019-03-13 15:18:29
当您有不实现可比较的对象,但您想要对包含它们的集合进行排序时,您要么必须扩展它们来对您的集合进行排序,要么提供一个比较器对它们进行比较,即使它们是不可比较的。
或者,您可能希望以不同于其自然排序的方式对这些对象进行比较排序。
想象一下这样一个例子。String是一个可比较的对象。假设您想要根据字符串的hashCode而不是字符串的自然顺序对字符串集合进行排序。如果不创建一个比较器,你会怎么做呢?
发布于 2019-03-13 15:21:02
您已经展示了使用Comparable确实有多个排序顺序,但是您不认为这是太多的样板代码吗?假设您在类中添加了一个名为name的新字段,现在您想要按名称排序。你必须:
compareTo.
使用您所展示的方法的另一个缺点是不一定清楚这意味着什么:
Arrays.sort(student);您必须检查您的代码,并检查您设置的comparator的值。
另外,如果我正在使用您的类,并且我想按其他方式排序,那么无论如何我都必须创建一个Comparator,因为我不能编辑您的类。
但是如果你使用Comparator,你就可以解决所有这些问题:
Arrays.sort(students, Comparator.comparing(Student::getName));因此,只有当有一个自然的顺序时,Comparable才有用,例如日期和时间。
https://stackoverflow.com/questions/55136231
复制相似问题