首页 > 解决方案 > Java 和可比的

问题描述

我是新来的,这是我的第一篇文章。我刚刚完成了我的 Java OCA,现在开始学习 OCP。我有一个关于 Comparable 接口的问题。

我有这个代码片段,它解释了 Comparable 是如何实现的:

import java.util.*;
public class Duck implements Comparable<Duck> {
private String name;
public Duck(String name) {
this.name = name;
}
public String toString() {   // use readable output
return name;
}
public int compareTo(Duck d) {
return name.compareTo(d.name); // call String's compareTo
}
public static void main(String[] args) {
List<Duck> ducks = new ArrayList<>();
ducks.add(new Duck("Quack"));
ducks.add(new Duck("Puddles"));
Collections.sort(ducks); // sort by name
System.out.println(ducks); // [Puddles, Quack]
}
}

我或多或少地了解这里发生了什么,但在此代码片段下面作者引用了以下内容:

Duck 类实现了 Comparable 接口。如果不实现该接口,我们只有一个名为 compareTo() 的方法,但它不是 Comparable 对象。

我的问题是为什么它不能具有可比性?这是否与调用诸如 之类的代码Collections.sort()会在内部使用 Comparable 类型作为参考参数来比较任何对象的事实有关?

提前感谢您的帮助,我希望我的问题有意义。

标签: javacomparableopen-closed-principle

解决方案


Java 是一种基于面向对象的语言。支持通过类继承/通过类/抽象类/接口实现多态性

interface Comparable<T> {
  // methods
}

class Person implements Comparable<Person> {
//methods
}

这实质上意味着 Person 类型的任何对象也属于 Comparable 类型。

interface Runnable {}
class Task implements Runnable {}

这意味着任何由 Task 类创建的对象也是 Runnable 类型的。

这就是作者的意思。

如果您没有实现 Comparable 接口,但定义了 compareTo() 方法,那么您只是在类中定义了一个方法,就像任何其他方法一样。您没有覆盖定义的 Comparable 接口中的 compareTo() 方法。

您仍然可以使用 compareTo() 方法比较每个对象,但您需要定义自己的排序方法,该方法在内部调用 compareTo() 方法以排序方式获取列表。

Java API Collections.sort() 在内部将列表转换为 Object[] 并调用 Arrays.sort()。现在 Arrays.sort() 将使用 TimSort 算法的修改版本进行排序,并且约定是 - 它仅对 Array 的元素进行排序,前提是它们是 Comparable 类型。

  • 可比时间排序
  • 集合.sort()

您可以检查所有内部呼叫,它清楚地说明:

@throws IllegalArgumentException(可选)如果发现比较器违反 {@link Comparator} 合同

因此,要将任何对象类型传递给 sort(),它也必须是 Comparable 类型。字符串/包装器已经属于 Comparable 类型。因此,您需要在定义用户定义的对象时处理此合同。

“如果不实现该接口,我们只有一个名为 compareTo() 的方法,但它不会是 Comparable 对象。”

-简单地说,这意味着没有实现接口,你有一个 Duck 类型的对象,而不是可比较的类型


推荐阅读