Comparable 和 Comparator 如何在 Collections 中工作?

How Comparable and Comparator work in Collections?

此代码来自著名的 Java SCJP6 书籍。我无法理解 compareTo 方法中 titled.getTitle() 之间的区别。 titled.getTitle() 如何获取和比较值?

class DVDInfo implements Comparable<DVDInfo> {
    String title;
    String genre;
    String leadActor;

    DVDInfo(String t, String g, String a) {
        title = t; genre = g; leadActor = a;
    }

    public String toString() {
        return title + " " + genre + " " + leadActor + "\n";
    }

    public int compareTo(DVDInfo d) {
        return title.compareTo(d.getTitle());
    }

    public String getTitle() {
        return title;
    }

    // other getters and setters
}

compareTo()方法中比较了两个实例。当你从外面使用它时,它看起来像这样:

DVDInfo first = new DVDInfo("title1");
DVDInfo second = new DVDInfo("title2");

// compare
first.copareTo(second);

您可以看到 compareTo() 方法在 "first" DVDInfo 实例范围内被调用。

在 class 中实现 compareTo() 时,您将获得 "second" 实例作为参数:

public int compareTo(DVDInfo other) {
     // 'title' is the local field (this.title)
     // 'other.getTitle()' is the title from the 'other' (second) instance
     return title.compareTo(other.getTitle());
}

您显示的 compareTo() 方法通过比较两个 object 的标题来比较它们。也就是说,它按标题对 DVD 进行排序。标题为 "New York New York" 的 DVD 将出现在标题为 "Breakfast At Tiffany's" 的 DVD 之后,无论 DVDInfo object.

中的所有其他字段如何

因此,compareTo() 依赖于 title 字段的 compareTo() 方法,它是类型 String 的 object。 String 实现了 Comparable,因此有一个 compareTo() 方法可以按字典顺序对字符串进行排序。

返回的结果是比较当前 object 的标题和给定 object 的标题。在我看来,比较应该是双方的 getTitle()(假设 getTitle() 将被覆盖并考虑到这一点)或双方的 title(考虑方法是如果有人覆盖 getTitle() 他们也应该覆盖 compareTo())。但这也许是opinion/style的问题。不过,最重要的是,这两个都是字符串,这些字符串代表 DVD 的标题,这些字符串相互比较以产生要从 [=13 返回的正值、零值或负值=] DVDInfo.


取两个 object 类型的 DVDInfo:

DVDInfo dvd1 = new DVDInfo( "Titanic", "Drama", "Leonardo DiCaprio");
DVDInfo dvd2 = new DVDInfo( "Guardians Of The Galaxy", "Adventure", "Chris Pratt" );

现在,如果你 运行

int result = dvd1.compareTo(dvd2);

"current" object(运行 方法)是 dvd1。它的 title 字段包含字符串 "Titanic"。参数 d 是对 dvd2 引用的 object 的引用。所以它的标题是"Guardians Of The Galaxy",这就是方法d.getTitle() returns。现在它比较这两个字符串,比较等价于:

"Titanic".compareTo("Guardians Of The Galaxy")

其中returns13(正数,表示"Titanic"大于"Guardians Of The Galaxy")。