首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可比较和比较接口

可比较和比较接口
EN

Stack Overflow用户
提问于 2019-03-13 15:09:17
回答 4查看 72关注 0票数 1

通常说,比较器用于具有对象集合的多个排序序列,而可比较用于具有单个排序序列。当使用可比较的接口可以有多个排序序列时,在java中比较器接口的用途是什么?

代码语言:javascript
复制
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);
        }
    }
}
EN

回答 4

Stack Overflow用户

发布于 2019-03-13 15:21:09

当您的compareTo方法根据某个static变量的值具有不同的行为时,基本上就是引入了一个全局设置来控制Student类的自然顺序。

这可能会使您的类的用户感到困惑和违反直觉。

此外,这使得compareTo的实现变得很笨拙,特别是当您有两个以上的实现,并且每个实现都依赖于多个实例变量时。

对于为同一个类的实例提供多个不同的比较,Comparator是一个更合适的接口,每个实现都有自己的compare()逻辑。

票数 1
EN

Stack Overflow用户

发布于 2019-03-13 15:18:29

当您有不实现可比较的对象,但您想要对包含它们的集合进行排序时,您要么必须扩展它们来对您的集合进行排序,要么提供一个比较器对它们进行比较,即使它们是不可比较的。

或者,您可能希望以不同于其自然排序的方式对这些对象进行比较排序。

想象一下这样一个例子。String是一个可比较的对象。假设您想要根据字符串的hashCode而不是字符串的自然顺序对字符串集合进行排序。如果不创建一个比较器,你会怎么做呢?

票数 0
EN

Stack Overflow用户

发布于 2019-03-13 15:21:02

您已经展示了使用Comparable确实有多个排序顺序,但是您不认为这是太多的样板代码吗?假设您在类中添加了一个名为name的新字段,现在您想要按名称排序。你必须:

  • 将新案例添加到compareTo.

  • 将新案例添加到枚举

使用您所展示的方法的另一个缺点是不一定清楚这意味着什么:

代码语言:javascript
复制
Arrays.sort(student);

您必须检查您的代码,并检查您设置的comparator的值。

另外,如果我正在使用您的类,并且我想按其他方式排序,那么无论如何我都必须创建一个Comparator,因为我不能编辑您的类。

但是如果你使用Comparator,你就可以解决所有这些问题:

代码语言:javascript
复制
Arrays.sort(students, Comparator.comparing(Student::getName));

因此,只有当有一个自然的顺序时,Comparable才有用,例如日期和时间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55136231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档