Vanillo.schnitzel
Vanillo.schnitzel

Reputation: 115

How to implement compareTo method in Java and what does it mean

I'm very new to java. I know that the Java Comparable interface has only one method, which has an int return type. However, I'm not sure what I am actually doing when I want to override the compareTo method. It's important to me to understand programming and not just memorizing it.

For example, in the following code we have an int variable spaceshipClassComparison, which is equal to this.spaceshipClass.compareTo(other.spaceshipClass). I know that this method returns the values: 1, 0, -1. But, I don't understand what we are doing when we call compareTo() again for this.spaceship but this time with a new object. How does it turn to int?

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);
    }
}    

Upvotes: 0

Views: 8256

Answers (2)

dani-vta
dani-vta

Reputation: 7130

I think you're struggling to understand what happens in your compareTo() definition because of the further use of String.compareTo().

String.compareTo() simply performs an alphabetical comparison to establish if the current string is lower, equal or greater than the String argument. In your snippet, you're basically comparing two Spaceship objects by their spaceshipClass first, and by their registrationNo second. This means, that if two instances are alphabetically different by their spaceshipClass, you simply return the result (where the argument might be lower or greater than your object). Otherwise, if the objects are equal by their spaceshipClass, their registrationNo is compared, returning the result.

Let's make a simpler example with another class, where there is no further invocation of compareTo(). In this scenario, the Person class contains the following fields: name, lastName, and age, and we want to establish its natural ordering by age.

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;
    }

    // ... setters and getters ...

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

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

        // Here, there are no other cases left 
        // so we return 1 because the current person is "greater" than the other
        return 1;
    }

    public static void main(String[] args) {
        Person p1 = new Person("Matt", "O'Brien", 45);
        Person p2 = new Person("Conan", "O'Brien", 61);
        Person p3 = new Person("Andy", "Richter", 61);

        // Prints -1 because 45 is lower than 61
        System.out.println(p1.compareTo(p2));

        // Prints 1 because 61 is greater than 45
        System.out.println(p2.compareTo(p1));

        // Prints 0 because 61 is equal to 61. 
        // even though we're comparing different people
        System.out.println(p2.compareTo(p3));   
    }
}

Here is a link to the Java Tutorials that expands on the topic of object ordering.

Upvotes: 0

Andrew
Andrew

Reputation: 110

In cases when we compare obvious things like numbers, we don't need a custom compareTo method. So for example, if we want to know if 2 is greater than 1 we just use the appropriate operator: 2 > 1

However when we're dealing with things that aren't obviously comparable, like objects and spaceships (in your example), we need to explain to the compiler what criterion is used to say that one spaceship is "bigger" than another.

This is where writing a custom (@Override) compareTo method comes in. By default the compareTo method returns either 1, 0 or -1. There is no inherent meaning to these numbers, in fact they can be any numbers you like (as long as they are different). Their purpose is to match three cases when two things are compared:

  • thing 1 is greater than thing 2
  • thing 1 is equal to thing 2
  • thing 1 is less than thing 2

The compareTo method in your example specifies that when we compare two spaceships we are going to use the string value of their spaceshipClass. Furthermore, the compareTo method in your example uses the default implementation of comparing strings: This means that the strings are compared lexicographically (you can think of it as alphabetical).

Upvotes: 0

Related Questions