【问题标题】:Why use compareTo() from Comparable Interface when overriding the compareTo() method? [closed]为什么在覆盖 compareTo() 方法时使用 Comparable Interface 中的 compareTo()? [关闭]
【发布时间】:2016-11-18 03:34:09
【问题描述】:

我一直在谷歌搜索,最接近的回复(未回答)是here,但我对回复感到困惑。我正在尝试使用 Collection.sort() 对一些狗的名字进行排序,所以我需要学习使用 Comparable 接口。我的问题:

1) 当我“覆盖” compareTo() 时,为什么需要使用来自接口的 compareTo()?
2) 如果 Comparable 接口中的 compareTo() 是默认方法,为什么在方法前面没有“default”关键字? Java SE 8 Menu

这里是部分代码:

Collections.sort(list);   
for(Dog a: list)   // printing the sorted list of names
     System.out.print(a.getDogName() + ", ");

这是实现 Comparable 接口的类:

class Dog implements Comparator<Dog>, Comparable<Dog> {
   private String name;
   private int age;

   Dog() {}

   Dog(String n, int a) {
      name = n;  age = a;
   }

   public String getDogName() {
      return name;
   }

   public int getDogAge() {
      return age;
   }

   public int compareTo(Dog d) {
      return (this.name).compareTo(d.name);  //###.....my question
   }

   // Override Comparator Interface's compare() to sort "ages"
   public int compare(Dog d, Dog d1) {
      return d.age - d1.age;
   }
}

【问题讨论】:

  • 你所说的“使用”是什么意思,如何在没有方法覆盖的情况下覆盖方法?它在哪里说这是一个default 方法?不清楚你在问什么。
  • @EJP ,当他们谈论创建自己的 Comparable 接口的 compareTo 方法时,这是在线使用“覆盖”一词的一堆文章中的一个示例。 tutorialspoint.com/java/java_using_comparator.htm
  • @EJP,另外,一个接口可以有一个自 Java 8 以来已经在接口中实现的默认方法。因为我发现的许多文章在实现 Comparable 接口时都说“覆盖” compareTo() 并且它们将 compareTo() 称为默认方法,我在帖子中询问 compareTo() 是否是默认方法。
  • 你没有在你的问题中问这个问题。您问 为什么 它没有 default 如果 它是默认方法。这个问题没有意义。它只是一个默认方法if,它的声明中有default。你似乎不明白自己的问题。
  • @EJP ,我看你不明白我的问题。大声笑

标签: java interface comparable


【解决方案1】:

这里有一些需要考虑的事情。

DogComparable 到其他 Dogs。它本身并不是比较两个 other Dogs 的东西。

所以,实现Comparable 是“更正确的”。

而且你有两种方法冲突。

static &lt;T extends Comparable&lt;? super T&gt;&gt; void sort(List&lt;T&gt; list)

按照升序对指定列表进行排序 其元素的自然排序。

所以,Collections.sort(dogs); 将对您的列表进行排序。

static &lt;T&gt; void sort(List&lt;T&gt; list, Comparator&lt;? super T&gt; c)

根据由 指定的比较器。

这就是您使用该方法的方式。

Collections.sort(dogs, new Comparator<Dog>() {
    @Override
    public int compare(Dog d1, Dog d2) {
        return d1.compareTo(d2); // Call the Comparable method
    }
)};

当然,您可以实现按年龄排序的内部方法

return Integer.compare(d1.getAge(), d2.getAge());

【讨论】:

  • 谢谢,@cricket_007。但是从该行实现的原始 compareTo() 在哪里, return d1.compareTo(d2); ?
  • Dog implements Comparable&lt;Dog&gt;
  • 是的。怎么样?
  • Collections.sort(dogs, new Comparator() {......}); =>您的答案中的这一行实现了 Comparator 接口。但是 Comparator 接口没有 compareTo() 被覆盖。为什么调用 Comparable 方法?谢谢你的帮助。 :)
  • 好的,我打错了。对此感到抱歉
【解决方案2】:

为什么我需要使用来自接口的 compareTo() “覆盖” compareTo()?

这样您就可以根据使用的数据结构自定义逻辑,因此在您的情况下,您使用的是 Dog 对象,该对象无法由 Collection API 默认排序,因为它们仅对原始数据类型进行排序,而不对自定义对象进行排序。

所以它要求覆盖 compareTo() 并提供自定义逻辑,因为您的排序关键字是 String "name",您可以使用它的 compareTo() 方法进行排序。

2) 如果 Comparable 接口中的 compareTo() 是默认方法, 为什么方法前面没有“default”关键字?

因为在原始数据类型排序的情况下,Collections.sort() 内部使用Arrays.sort(),并且 Comparable 接口中没有 compareTo() 方法的默认实现

【讨论】:

  • 根据您解释的第一部分,在我看来,Comparable 接口附带的原始 compareTo() 已经实现了对 String 对象进行排序,对吧?