1

I'm getting the following error when trying to run this little program:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at MainClass.main(Person.java:120)
Caused by: java.lang.RuntimeException: Uncompilable source code - FirstNameComparator is not abstract and does not override abstract method compare(java.lang.Object,java.lang.Object) in java.util.Comparator
    at FirstNameComparator.<clinit>(Person.java:71)
    ... 1 more
Java Result: 1

Please tell me what I'm doing wrong, and of course it would help a short example with explanations about how to properly use Comparator and Comparable.

import java.util.*;
import java.lang.*;

public class Person implements Comparable {

    private String firstName;
    private String lastName;
    private int age;

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName= lastName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setAge(int age) {
        this.age=age;
    }
    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Object anotherPerson) throws ClassCastException {
        if(!(anotherPerson instanceof Person)) {
            throw new ClassCastException("A person object expected !");
        }
        int anotherPersonAge = ((Person)anotherPerson).getAge();
        return this.age = anotherPersonAge;
    }

}

LastNameComparator.java

class LastNameComparator implements Comparator  {

    public int compareTo(Object person, Object AnotherPerson)  {
        String lastName1 = ((Person)person).getLastName().toUpperCase();
        String firstName1= ((Person)person).getFirstName().toUpperCase();
        String lastName2 = ((Person)person).getLastName().toUpperCase();
        String firstName2 = ((Person)person).getFirstName().toUpperCase();

        if(lastName1.equals(lastName2)) {
            return firstName1.compareTo(firstName2);

        }else {
           return lastName1.compareTo(lastName2);

        }
    }

    }   

FirstNameComparator.java

class FirstNameComparator implements Comparator {

    public int compareTo(Object person, Object anotherPerson) {

        String lastName1 = ((Person)person).getLastName().toUpperCase();
        String firstName1 = ((Person)person).getFirstName().toUpperCase();
        String lastName2 = ((Person) person).getLastName().toUpperCase();
        String firstName2 = ((Person) person).getFirstName().toUpperCase();

        if(firstName1.equals(lastName1)) {
            return lastName1.compareTo(lastName2); 

        }else {
            return firstName1.compareTo(firstName2);
        }

    }
}

MainClass.java

class MainClass  {

    public static void main(String[] args) {

        Person[] persons = new Person[4];
        persons[0] = new Person();
        persons[0].setFirstName("Asaftei");
        persons[0].setLastName("Ionut");
        persons[0].setAge(25);

        persons[1] = new Person();
        persons[1].setFirstName("Binoclu");
        persons[1].setLastName("Telescop");
        persons[1].setAge(10);

        persons[2] = new Person();
        persons[2].setFirstName("Morcov");
        persons[2].setLastName("Castravete");
        persons[2].setAge(33);

        persons[3] = new Person();
        persons[3].setFirstName("Rosie");
        persons[3].setLastName("Ardei");
        persons[3].setAge(55);

        System.out.println("Natural Order : ");
        for(int counter =0; counter<=3; counter++)  {
            Person person = persons[counter];
            String lastName=person.getLastName();
            String firstName=person.getFirstName();
            int age = person.getAge();
            System.out.println(lastName+ ", " +firstName+ " , "+age);
        }

        Arrays.sort(persons, new FirstNameComparator());
        System.out.println();
        System.out.println("Sorted by First Name: ");
        for(int counter=0; counter<=3; counter++) {
            Person person = persons[counter];
            String lastName = person.getLastName();
            String firstName = person.getFirstName();
            int age = person.getAge();

            System.out.println(lastName+ ", " +firstName+ ", " +age );
        }
        Arrays.sort(persons, new LastNameComparator());
        System.out.println();
        System.out.println("Sorted by Last Name");        for(int counter=0; counter<=3; counter++) {
            Person person = persons[counter];
            String lastName = person.getLastName().toUpperCase();
            String firstName = person.getFirstName().toUpperCase();
            int age = person.getAge();
            System.out.println(lastName +", "+firstName+", "+age);
        }
    }
}
Mureinik
  • 252,575
  • 45
  • 248
  • 283
  • When implementing interfaces be sure to always use the [`@Override`](http://stackoverflow.com/q/94361/113632) annotation. It will give you a clear compilation error if you accidentally override the wrong method. IDEs like Eclipse can also be configured to warn you when you forget the annotation. – dimo414 Jul 18 '15 at 22:35
  • Also notice that your comparators never use `anotherPerson` - another bug Eclipse will warn you about. – dimo414 Jul 18 '15 at 22:39
  • Thanks a lot. I've used @Override annotation and i've changed the compareTo into compare. That solved my problem. Now it works fine without errors. Thanks a lot everybody !!! – Ionutz Asaftei Jul 19 '15 at 11:06

2 Answers2

2

Comparators need to implement the compare method, not a compareTo method.

So, e.g., your FirstNameComparator should look like this:

class FirstNameComparator implements Comparator {

    @Override
    public int compare(Object person, Object anotherPerson) {
        // implementation
    }
}

Note that since this Comparator is used to compare Person instances, it would be a better practice to use generics syntax and define it as such:

class FirstNameComparator implements Comparator<Person> {

    @Override
    public int compare(Person person, Person anotherPerson) {
        // implementation
    }
}
Mureinik
  • 252,575
  • 45
  • 248
  • 283
1

Don't forget Comparable takes in generic type arguments. So use implements Comparable<Person> instead. This means that you can compare two Persons.

Also an overriding method is not allowed to add additional throws to the method. See this question

The new definition should be something like this:

@Override
public int compareTo(Person other) { 
    return Intger.compare(this.getAge(), other.getAge());
}
Community
  • 1
  • 1
Aarjav
  • 1,135
  • 8
  • 19