user6818508
user6818508

Reputation: 17

Working with Comparator<T>

Good Day-

I'm working on a task in which I've directives to create a method named as void sortByAthleteNames() which will do the following task:

Sort the list of Athlete objects by first and last names. This method calls the sort method defined in the Sorts class, using an object of AthleteNameComparator class as its second parameter

Sorts Class has the following implementation:

public class Sorts {

    public static void sort(ArrayList<Athlete> objects,Comparator<Athlete> comparator)
    {
        //TODO
    }
}

Your sort method utilizes the compare method of the parameter Comparator object to sort. You can use one of Selection sort or Insertion Sort.

sortByAthleteNames() method implemetation:

public void sortByAthleteNames() {
        AthleteNameComparator athleteNameComparator = new AthleteNameComparator();      
        Sorts.sort(athleteList, **CONFUSED WHAT TO PASS HERE**);
    }

whereas AthleteNameComparator class has the following directives:

The AthleteNameComparator class implements the "Comparator" interface. It needs to define the following method that was an inherited abstract method from Comparator interface:

public int compare(Object first, Object second) (Note that you can also define: public int compare(Athlete first, Athlete second) instead by making the class implements Comparator.

For this I have created a class which is as follow:

AthleteNameComparator

public class AthleteNameComparator implements Comparator<Athlete>{

    @Override
    public int compare(Athlete o1, Athlete o2) {
        // TODO Auto-generated method stub
        return 0;
    }
}

Furthermore we have the following directives which we need to implement this in the same method and those are as follow:

If the first argument object has a last name lexicographically less than that of the second argument, an int less than zero is returned. If the first argument object has a last name lexicographically larger than that of the second argument, an int greater than zero is returned. If their last names are same, then their first names should be compared. If they have same first and last names, then 0 should be returned.

I'm confused here. My question is how can I perform a relational operators because the datatype of the lastName is String and returned -1/1 or 0. I have searched a lot and according to my understanding that's how I can compare these. Please confirm is this the right way to do this?

public class AthleteNameComparator{

    public int compare(Athlete a1, Athlete a2) {

        if(a1.getLastName().hashCode() < a2.getLastName().hashCode())
        {
            return -1;
        }
        else if(a1.getLastName().hashCode() > a2.getLastName().hashCode())
        {
            return 1;
        }
        else if(a1.getLastName().hashCode() == a2.getLastName().hashCode())
        {
            if(a1.getFirstName().hashCode() == a2.getFirstName().hashCode())
            {
                return 0;
            }
        }
        return 100;
    }
}

But again why we are doing this? what would we achieve with -1/1 or 0. Also could you please explain the follow of this that how could it will work. Which things I need to take care of first and when I get the successful response from the compare() method then how could I use the returned value in Insertion or Selection sort.

Many Thanks

Upvotes: 0

Views: 1170

Answers (1)

Anonymous
Anonymous

Reputation: 86173

Sorting using comparators is a standard thing to do in Java. For how it works and why the compare method has to return a negative/positive/0 value, find the tutorials and other resources on the net and/or in your text book.

It’s really silly to require a specific class name, as AthleteNameComparator, but assuming it’s a school assignment, you should probably go by it.

The call to sort is straightforward:

    Sorts.sort(athleteList, athleteNameComparator); // **SEE WHAT TO PASS HERE**

Your skeleton for AthleteNameComparator is correct. You may fill in the method like:

@Override
public int compare(Athlete o1, Athlete o2) {
    int diffLastName = o1.getLastName().compareTo(o2.getLastName());
    if (diffLastName == 0) { // last names are equal
        return o1.getFirstName().compareTo(o2.getFirstName());
    } else {
        return diffLastName;
    }
}

Once you get the hang of it, writing comparators is easy: you just pass (delegate) the task to the appropriate compareTo (more seldom to another comparator’s compare method), and it will return the correct negative or positive or 0 value. You don’t even have to keep track of which is which as long as you keep left hand side (o1) and right hand side (o2) in their correct places.

If it wasn’t for the requirement on the class name, sortByAthleteNames() could be written with just a few lines of code including the comparator (assuming Java 8):

public void sortByAthleteNames() {
    Sorts.sort(athleteList, Comparator.comparing(Athlete::getLastName).thenComparing(Athlete::getFirstName));
}

If I understand correctly, you still have the greater part of the work in front of you: implementing Sorts.sort(). If you start from a sort algorithm that compares elements using, say, e1 < e2, you will have to replace it by comparator.compare(e1, e2) < 0. Always use the same relational operator as the original algoritm and it should go smoothly.

Hope it helps.

Upvotes: 1

Related Questions