当前位置: 首页 > 知识库问答 >
问题:

关于在java中重写compareTo方法的一个问题

楚元章
2023-03-14

首先,很抱歉提出这样的问题,我对html" target="_blank">java非常陌生。我知道java Comparable Interface只有一个methode,它有一个int返回类型。然而,当我想要覆盖compareTo方法时,我不确定我到底在做什么。对我来说,理解编程很重要,而不仅仅是记住它。例如,在下面的代码中,我们有一个int变量“spaceshipClassComparison”,它等于“this.spaceshipClass.comparieto(other.spaceshipClass)”。我知道这个方法返回的值是1,0,-1,但是我不明白当我们再次为此调用compareTo()时我们在做什么。宇宙飞船,但这次有了一个新的物体,它是如何变成整数的?

public class Spaceship implements Comparable<Spaceship> {

private String spaceshipClass = null;
private String registrationNo = null;

public Spaceship(String spaceshipClass, String registrationNo) {
    this.spaceshipClass = spaceshipClass;
    this.registrationNo = registrationNo;
}

@Override
public int compareTo(Spaceship other) {
    int spaceshipClassComparison =
            this.spaceshipClass.compareTo(other.spaceshipClass);

    if(spaceshipClassComparison != 0) {
        return spaceshipClassComparison;
    }
    
    return this.registrationNo.compareTo(other.registrationNo);
}
 }    

共有2个答案

苏鸿才
2023-03-14

当我们比较数字等显而易见的东西时,我们不需要自定义compareTo方法。例如,如果我们想知道2是否大于1,我们只需使用适当的运算符:2

然而,当我们处理一些不明显可比的东西时,比如物体和宇宙飞船(在你的例子中),我们需要向编译器解释使用什么标准来表示一个宇宙飞船比另一个“大”。

这就是编写自定义(@Override)compareTo方法的用武之地。默认情况下,compareTo方法返回1、0或-1。这些数字没有内在的意义,事实上它们可以是你喜欢的任何数字(只要它们不同)。它们的目的是在比较两种情况时匹配三种情况:

  • 第一件事比第二件事大

示例中的compareTo方法指定,当我们比较两个宇宙飞船时,我们将使用它们的spaceshipClass的字符串值。此外,您的示例中的compareTo方法使用了比较字符串的默认实现:这意味着按字典顺序比较字符串(您可以将其视为按字母顺序)。

太叔炎彬
2023-03-14

compareTo方法用于在类的元素之间建立自然排序。这是一个扩展自然排序概念的链接。

https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

回到您的示例,我认为您在理解它的概念时遇到了困难,因为您正在比较两个String对象,这两个对象反过来调用它们的compareTo实现,后者在后台执行其他操作。基本上,它们只是按字母顺序进行比较,以确定当前字符串是否低于、等于或大于给定参数。

不过,让我们用另一个类来做一个更简单的例子。假设我们有一个Person类,它只包含名字、姓氏和年龄,我们希望通过比较不同年龄的人来建立其自然顺序。

class Person implements Comparable<Person> {
    private String name, lastName;
    private int age;

    public Person(String name, String lastName, int age) {
        this.name = name;
        this.lastName = lastName;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Person otherPerson) {
        //If the current person's age is lower than otherPerson's age than we return -1, as the current person is "lower" than the other (ordering-wise)
        if (age < otherPerson.getAge()) {
            return -1;
        }

        //If the current person's age is equal to the otherPerson's age than we return 0, as the current person is "equal" than the other (ordering-wise)
        if (age == otherPerson.getAge()) {
            return 0;
        }

        //Here, there are no other cases left so the current person's age is greater than the otherPerson's age, so we return 1.
        return 1;
    }

    public static void main(String[] args) {
        Person p1 = new Person("Matt", "O'Brien", 20);
        Person p2 = new Person("Matt", "O'Brien", 25);
        Person p3 = new Person("George", "Lucas", 25);

        System.out.println(p1.compareTo(p2));   //Prints -1 because 20 is lower than 25
        System.out.println(p2.compareTo(p1));   //Prints 1 because 25 is greater than 20
        System.out.println(p2.compareTo(p2));   //Prints 0 because 20 is equal to 20 even though we're comparing different people, because in the comprateTo we're only confronting the age
    }
}

在你的比较例子中,你所做的基本上是在太空船元素之间建立一个自然的顺序,首先按它们的类别,然后按它们的数量。事实上,如果它们类的字母顺序不同于0,则会立即返回该值。否则,如果它们的类相同,则执行另一次比较(通过注册号)并返回其值。

public int compareTo(Spaceship other) {
    //Saving the comparison value between the spaceships' class
    int spaceshipClassComparison =
            this.spaceshipClass.compareTo(other.spaceshipClass);

    //If they are already different by class we return the ordering value (no point in comparing also the number)
    if(spaceshipClassComparison != 0) {
        return spaceshipClassComparison;
    }
    
    //If the spaceships have the same class then we return the comparison between their registration number
    return this.registrationNo.compareTo(other.registrationNo);
}

 类似资料:
  • 我有一门狗和猫的课,看起来像这样: 这些类都实现了我创建的一个名为Speakable的接口,它看起来像这样: 这个Speakable接口之所以存在,是因为我需要一个引用变量,允许我将狗和猫添加到同一个ArrayList中,并且仍然在它们上调用说话()方法。 我还需要重写Comparable接口的compareTo()方法,以便比较狗的名字。调用此方法时,我认为我的代码如下所示:a.compareT

  • 当实现Comparable接口并重写compareTo方法时, 第三行,我意识到当我重写它时,我可以使用compareTo,它会自动按照自然顺序进行比较。但是在可比较的界面中,它不是一个抽象的方法。没有定义它,它还可以比较吗?还有,为什么我不需要使用super关键字来区分这个比较。

  • 在android studio中,不能从静态上下文引用非静态方法“put(java.lang.String,java.lang.String)”是什么意思?

  • 我正在开发一个程序,该程序必须重写Comparable中的CompareTo(),以生成集合。排序()工作。因为我使用的是一个由助手组成的ArrayList,我必须根据名称进行排序。 我环顾了论坛,发现了这一点,并尝试改变 到 作为回报,我可以使用这些收藏。sort()在另一个类中,并且没有警告我任何错误,但是,出现了两个新错误。 首先,在同一行中 它告诉我“它不是抽象的,也不会覆盖Compara

  • 问题内容: 我正在编写一个类,该类将一堆银行帐户放入数组列表中,并根据其帐号进行排序。我写的方法如下: 在我的主要方法中,是数组列表的变量。当我尝试执行操作时无法执行此操作。它给我一个错误,说出诸如“无法从参数实例化,因为实际参数和形式参数的长度不同”和“推断的类型不符合声明的边界”之类的错误。我以为这是由于我没有重写方法,但是当我尝试这样做时,它说“方法不会重写或实现超类型的方法”。我不明白问题