【问题标题】:Comparator works for my ArrayList but code looks wrong?比较器适用于我的 ArrayList 但代码看起来不对?
【发布时间】:2014-03-17 08:48:55
【问题描述】:

我有一个名为 Course 的对象的 ArrayList,我试图以 2 种方式对它进行排序,按 courseID 和课程开始时间。

class Course implements Comparable<Course> {
    private int courseID;
    private String courseBeginTime;

    // implement the compareTo method defined in Comparable
    @Override
    public int compareTo(Course course) {
        if (getCourseID() > course.getCourseID()){
            return 1;
        } else if(getCourseID() < course.getCourseID()){
            return -1;
        } else {
            return 0;
        }       
    }

然后我有这些比较器:

//implement the comparators
class IDSorter implements Comparator<Course> {
    public int compare(Course course1, Course course2) {
        return Integer.compare(course1.getCourseID(), course2.getCourseID());
    }
}

class startTimeSorter implements Comparator<Course> {
    public int compare(Course course1, Course course2) {
        return Integer.compare(Integer.parseInt(course1.getCourseBeginTime()),
                Integer.parseInt(course2.getCourseBeginTime()));
    }
}

我在我的主要方法中对它们进行排序,如下所示:

Collections.sort(courseList, new IDSorter());
Collections.sort(student.getStudentSchedule(), new StartTimeSorter());

代码有效,我可以得到按 ID 或 startTime 排序的列表....但我不明白为什么。在 Course 类中 compareTo 方法只是比较 getCourseID。

需要比较 courseBeginTime 的 StartTimeSorter 是如何工作的?

如何重写才能更有意义?

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    如果一个类实现了Comparable,这被认为是这个类的自然排序。当您没有将明确的Comparator 指定给Collections.sort 时,将使用此排序。这就是为什么 sort 的单参数版本采用 List&lt;T&gt; 其中 T extends Comparable&lt;? super T&gt;。两个参数版本采用对 T 没有限制的 List&lt;T&gt;Comparator&lt;? super T&gt;。所以Course.compareTo 在你的例子中没有使用。

    【讨论】:

    • 我可以在不使用创建自己的比较器的情况下以两种不同的方式对其进行排序吗?即使我不需要使用 compareTo 方法,我也觉得它很愚蠢,但编译器警告我无论如何我都需要实现它。
    • IDSorter 或实现 Comparable 都是多余的。 StartTimeSorter 仍然是必需的。如果所有排序都应该以统一的方式处理,我会坚持使用两个比较器。
    • 既然我使用的是自己的比较器,那么我应该在 compareTo 方法中写些什么呢?基本上我在那里写的任何东西都是毫无意义的,现在我在那里写的东西充其量只是误导。
    • 如果你不想自然排序,就不要实现 Comparable。如果它与 equals 不一致,甚至可能很危险(我想在您的示例中情况并非如此,假设 courseID 是唯一的)。我不得不承认这也适用于比较器。见stackoverflow.com/questions/12123960/…
    【解决方案2】:

    Collections.sort 方法有两种变体。将单个参数作为 Comparable 对象的集合。另一个有两个参数:第一个是集合,第二个是比较器。您使用了第二个变体。因此不使用您的 compareTo 方法。

    【讨论】:

    • 知道了,所以我基本上得到了我的 compareTo 方法中的代码没有使用。所以在这种情况下,我不使用 compareTo,我仍然必须实现它,否则编译器会警告我我需要实现它。作为标准做法,如果我不使用它,我应该在那里输入什么代码?我必须为 compareTo 方法返回一些东西。
    • 你不需要实现它,因为你不需要实现 Comparable 接口。
    【解决方案3】:

    如果您在Collections.sort 方法中指定Comparator,它将考虑到这一点,即使该类实现Comparable。尝试在 sort 方法中不传递 Comparator 进行排序,您将看到您所期望的,即 compareTo 方法启动。

    【讨论】:

    • 谢谢 我现在明白了。因此,如果我使用自己的比较器,那么我什至不使用 compareTo 方法。那么我应该在 compareTo 方法中编码什么?我需要实现它,因为我取消了 Course implements Comparable
    • 有两种方法可以比较您的课程。一种是让类实现Comparable,另一种是在Collections的sort方法中传递Comparator。后者是首选,因为您不仅仅将一个比较逻辑绑定到类,而是可以通过不同的比较器实现以多种方式对类进行排序
    【解决方案4】:

    我认为你的 compareTo 方法只需要这样:

    @Override
    public int compareTo(Course course) {
        if (getCourseID() > course.getCourseID()){
            return 1;
        } else if(getCourseID() < course.getCourseID()){
            return -1;
        } else {
            return Integer.compare(Integer.parseInt(getCourseBeginTime()),
                Integer.parseInt(course.getCourseBeginTime()));
        }       
    }
    

    【讨论】:

      猜你喜欢
      • 2020-05-22
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 2021-09-17
      相关资源
      最近更新 更多